Enode Developers

Scheduling

A Schedule is a policy that targets a specific device (vehicle/charger/HVAC) at a specific Charging Location. It describes whether the target should be charging at any given point in time, or in the case of HVAC, what its target temperature & deadband should be. These values are called shouldCharge and target, respectively.

Hardware kindScheduled property
VehicleshouldCharge
ChargershouldCharge
HVACtargetTemperature

Constructing a ScheduleCopy link

A vehicle schedule policy begins by choosing a default value for shouldCharge, typically false.

Sample

{
  "defaultShouldCharge": false
}

The policy then specifies 0 or more rules that override the value of shouldCharge within certain timespans and situations:

Sample

{
  "defaultShouldCharge": false,
  "rules": [
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "01:00",
        "to": "04:00"
      },
      "weekdays": [0, 1, 2, 3, 4]
    },
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "01:00",
        "to": "09:00"
      },
      "weekdays": [5, 6]
    }
  ]
}

Each rule specifies a value for shouldCharge. All other keys are optional filters that can restrict the times and situations to which this rule applies:

Sample

{
  "shouldCharge": true,
  "hourMinute": {
    "from": "01:00",
    "to": "09:00"
  },
  "weekdays": [5, 6]
}

Supported FiltersCopy link

KeyDescription
hourMinutePair of UTC Clock times {"from": "xx:xx", "to": "xx:xx"} within which this rule should apply each day. from is inclusive, to is exclusive. to always resolves to a timestamp after from, and thus may span across midnight and fall on the next day.
fromTimestampUTC timestamp (inclusive) from which this rule should apply.
toTimestampUTC timestamp (exclusive) until which this rule should apply.
weekdaysAn array of weekdays to which this rule should apply. A weekday starts with 0 for Monday, and ends with 6 for Sunday.

Example Vehicle/Charger PoliciesCopy link

Always charge when possibleCopy link

This is the typical default behavior of EVs, and is equivalent to a null policy:

Sample

{
  "defaultShouldCharge": true,
  "rules": []
}

Prevent any charging until a future timeCopy link

Sample

{
  "defaultShouldCharge": true,
  "rules": [
    {
      "shouldCharge": false,
      "toTimestamp": "2020-01-07T16:21:76Z"
    }
  ]
}

Only charge between 01:00 and 06:00 each dayCopy link

Sample

{
  "defaultShouldCharge": false,
  "rules": [
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "01:00",
        "to": "06:00"
      }
    }
  ]
}

Only charge between 01:00 and 06:00 each work day, and any time on weekendsCopy link

Sample

{
  "defaultShouldCharge": false,
  "rules": [
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "01:00",
        "to": "06:00"
      }
    },
    {
      "shouldCharge": true,
      "weekdays": [5, 6]
    }
  ]
}

Set a custom charging window for every day of the weekCopy link

Sample

{
  "defaultShouldCharge": false,
  "rules": [
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "01:00",
        "to": "06:00"
      },
      "weekdays": [0]
    },
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "22:00",
        "to": "04:00"
      },
      "weekdays": [1]
    },
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "02:00",
        "to": "09:00"
      },
      "weekdays": [2]
    },
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "01:00",
        "to": "06:00"
      },
      "weekdays": [3]
    },
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "01:00",
        "to": "06:00"
      },
      "weekdays": [4]
    },

    // charge anytime on saturday
    {
      "shouldCharge": true,
      "weekdays": [5]
    },

    // two windows on Sunday
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "01:00",
        "to": "06:00"
      },
      "weekdays": [6]
    },
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "12:00",
        "to": "15:00"
      },
      "weekdays": [6]
    }
  ]
}

Example HVAC PoliciesCopy link

Target 20° during the day, and 15° at nightCopy link

Sample

{
  "defaultTarget": {
    "deadband": 2,
    "temperature": 20
  },
  "rules": [{
    "target": {
      "deadband": 2,
      "temperature": 15
    },
    "hourMinute": {
      "from": "23:00",
      "to": "06:00"
    }
  }
}

Target 20° during the day, 15° at night, and 7° until January 7, 2020Copy link

Sample

{
  "defaultTarget": {
    "deadband": 2,
    "temperature": 20
  },
  "rules": [{
    "target": {
      "deadband": 2,
      "temperature": 15
    },
    "hourMinute": {
      "from": "23:00",
      "to": "06:00"
    },
    {
      "target": {
        "deadband": 2,
        "temperature": 7
      },
      "toTimestamp": "2020-01-07T00:00:00",
    }
  }
}

Target 15° between 23:00 and 06:00 each work day, and until 08:00 on weekendsCopy link

Sample

{
  "defaultTarget": {
    "deadband": 2,
    "temperature": 20
  },
  "rules": [
    {
      "target": {
        "deadband": 2,
        "temperature": 15
      },
      "hourMinute": {
        "from": "23:00",
        "to": "06:00"
      }
    },
    {
      "target": {
        "deadband": 2,
        "temperature": 20
      },
      "hourMinute": {
        "from": "06:00",
        "to": "08:00"
      },
      "weekdays": [5, 6]
    }
  ]
}

Behavior across day/rule boundariesCopy link

Clock times can cross midnightCopy link

Sample

{
  "defaultShouldCharge": false,
  "rules": [
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "22:00", // If this is 22:00 on a Monday...
        "to": "06:00" // ...then this is 06:00 on a Tuesday
      }
    }
  ]
}

A rule is applied only during the intersection of all filtersCopy link

With the following configuration:

Sample

{
  "defaultShouldCharge": false,
  "rules": [
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "22:00",
        "to": "06:00"
      },
      "weekdays": [0]
    }
  ]
}

This rule only applies from 22:00 - 05:59 on the clock. Additionally, it only applies on Mondays. Thus:

  • Monday 00:00-05:59 - shouldCharge: true (inside 22:00-06:00, inside Monday)
  • Monday 21:00 - shouldCharge: false (outside 22:00-06:00)
  • Monday 22:00 - shouldCharge: true (inside 22:00-06:00 and inside Monday)
  • Tuesday 01:00 - shouldCharge: false (inside 22:00-06:00, but outside Monday)

When rules overlap, the latter one has precedenceCopy link

Sample

{
  "defaultShouldCharge": false,
  "rules": [
    {
      "shouldCharge": true,
      "hourMinute": {
        "from": "02:00",
        "to": "10:00"
      }
    },
    {
      "shouldCharge": false,
      "hourMinute": {
        "from": "08:00",
        "to": "09:00"
      }
    }
  ]
}
  • 00:00 - shouldCharge: false
  • 02:00 - shouldCharge: true
  • 08:00 - shouldCharge: false (inside 02:00-10:00, but also inside 08:00-09:00, which was defined later in the array)
  • 09:00 - shouldCharge: true (inside 02:00-10:00 only)

Reading current status of a Schedule

Every Schedule has a status object that describes the current status of its execution.

Receiving the Schedule Status objectCopy link

This object can be obtained at any time via the Get Schedule Status request.

It is additionally sent via webhook every time any of its values change, using the event user:schedule:execution-updated

Schema of the Schedule Status objectCopy link

Keep in mind that Schedules are all about scheduling a shouldCharge value, and that value is just one part of whether a target is expected to be charging. For example, if a Vehicle is scheduled to be charging, but is out driving on the road, it will not be charging. This is not a failure or problem from the scheduling point of view.

The scheduler combines the following properties to decide whether a target is expected to be charging:

  • needsCharge - Does the target want to charge?
  • isPluggedIn - Is the target connected to allow charging?
  • shouldCharge - Do the schedule rules dictate that the target should be charging?

If all are true, the target is expected to be charging. If any are false, the target is not expected to be charging. The execution engine always strives to keep the target's isCharging value equal to the expected value. This state where this is achieved is called ALIGNED. If it cannot be achieved, that is the state MISALIGNED.

Sample

{
  "scheduleId": "8d90101b-3f2f-462a-bbb4-1ed320d33bbe",
  "changedAt": "2019-08-24T14:15:22Z",
  "state": "ALIGNED",
  "isCharging": false,
  "isChargingExpected": false,
  "isChargingExpectedParts": {
    "needsCharge": true,
    "isPluggedIn": true,
    "shouldCharge": false
  },
  "upcomingTransitions": [
    {
      "at": "2020-04-08T02:00:00Z",
      "shouldCharge": true
    },
    {
      "at": "2020-04-08T06:00:00Z",
      "shouldCharge": false
    }
  ]
}

The state field always has one of the following values:

KeyDescription
ALIGNEDThe target's scheduled property is in the expected state.
MISALIGNEDThe target's scheduled property is stuck in an unexpected state.
PENDINGThe target's scheduled property is currently transitioning to the expected state.
INACTIVE:OVERRIDDENSchedule is inactive because an External Start has been created. Read more at the vehicle or charger External Start APIs.
INACTIVE:DISABLEDSchedule is inactive because its isEnabled property is false.
INACTIVE:AWAYSchedule is inactive because its target is away from the configured Charging Location.
INACTIVE:INCAPABLESchedule is inactive because its target is incapable of receiving charging actions.

The upcomingTransitions field returns up to 2 upcoming transitions of the shouldCharge field.