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

Copy linkConstructing a Schedule

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]
}

Copy linkSupported Filters

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.

Copy linkExample Vehicle/Charger Policies

Copy linkAlways charge when possible

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

Sample

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

Copy linkPrevent any charging until a future time

Sample

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

Copy linkOnly charge between 01:00 and 06:00 each day

Sample

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

Copy linkOnly charge between 01:00 and 06:00 each work day, and any time on weekends

Sample

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

Copy linkSet a custom charging window for every day of the week

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]
    }
  ]
}

Copy linkExample HVAC Policies

Copy linkTarget 20° during the day, and 15° at night

Sample

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

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

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",
    }
  }
}

Copy linkTarget 15° between 23:00 and 06:00 each work day, and until 08:00 on weekends

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]
    }
  ]
}

Copy linkBehavior across day/rule boundaries

Copy linkClock times can cross midnight

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
      }
    }
  ]
}

Copy linkA rule is applied only during the intersection of all filters

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)

Copy linkWhen rules overlap, the latter one has precedence

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.

Copy linkReceiving the Schedule Status object

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

Copy linkSchema of the Schedule Status object

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. Only applicable to schedules targeting vehicles. Any other entity type will never enter this state.
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.

Was this article helpful?