{"id":660,"date":"2026-05-31T20:11:00","date_gmt":"2026-05-31T18:11:00","guid":{"rendered":"https:\/\/e-car.day\/?page_id=660"},"modified":"2026-05-31T20:11:02","modified_gmt":"2026-05-31T18:11:02","slug":"ev-charging-schedule-optimizer","status":"publish","type":"page","link":"https:\/\/e-car.day\/?page_id=660","title":{"rendered":"EV Charging Schedule Optimizer"},"content":{"rendered":"\n<div class=\"eco-tool wp-block-group\" id=\"ev-schedule-calc-t18x\">\n  <div class=\"eco-tool__header\">\n    <h2 class=\"eco-tool__title\">EV Charging Schedule Optimizer<\/h2>\n    <p class=\"eco-tool__lead\">\n      Find the best charging window based on your arrival time, departure time, battery needs, and electricity tariff.\n    <\/p>\n  <\/div>\n\n  <form class=\"eco-tool__form\" id=\"ev-schedule-form-t18x\" novalidate>\n    <div class=\"eco-tool__grid3\">\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"sched-battery-t18x\">Battery size<br>(kWh)<\/label>\n        <input class=\"eco-tool__input\" id=\"sched-battery-t18x\" type=\"number\" min=\"1\" step=\"1\" value=\"75\" inputmode=\"decimal\">\n        <div class=\"eco-tool__hint\">Usable EV battery capacity.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"sched-current-t18x\">Current battery<br>level (%)<\/label>\n        <input class=\"eco-tool__input\" id=\"sched-current-t18x\" type=\"number\" min=\"0\" max=\"100\" step=\"1\" value=\"30\" inputmode=\"numeric\">\n        <div class=\"eco-tool__hint\">Battery level when you plug in.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"sched-target-t18x\">Target battery<br>level (%)<\/label>\n        <input class=\"eco-tool__input\" id=\"sched-target-t18x\" type=\"number\" min=\"1\" max=\"100\" step=\"1\" value=\"80\" inputmode=\"numeric\">\n        <div class=\"eco-tool__hint\">Battery level you want by departure.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"sched-power-t18x\">Charger power<br>(kW)<\/label>\n        <input class=\"eco-tool__input\" id=\"sched-power-t18x\" type=\"number\" min=\"0.5\" step=\"0.1\" value=\"7.4\" inputmode=\"decimal\">\n        <div class=\"eco-tool__hint\">Home wallbox is often 7.4\u201311 kW.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"sched-arrival-t18x\">Arrival time<br>(24h)<\/label>\n        <input class=\"eco-tool__input\" id=\"sched-arrival-t18x\" type=\"time\" value=\"18:00\">\n        <div class=\"eco-tool__hint\">When the EV becomes available to charge.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"sched-departure-t18x\">Departure time<br>(24h)<\/label>\n        <input class=\"eco-tool__input\" id=\"sched-departure-t18x\" type=\"time\" value=\"07:00\">\n        <div class=\"eco-tool__hint\">When charging must be finished.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"sched-offstart-t18x\">Cheap tariff starts<br>(24h)<\/label>\n        <input class=\"eco-tool__input\" id=\"sched-offstart-t18x\" type=\"time\" value=\"22:00\">\n        <div class=\"eco-tool__hint\">Start of cheaper electricity period.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"sched-offend-t18x\">Cheap tariff ends<br>(24h)<\/label>\n        <input class=\"eco-tool__input\" id=\"sched-offend-t18x\" type=\"time\" value=\"06:00\">\n        <div class=\"eco-tool__hint\">End of cheaper electricity period.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__field\">\n        <label class=\"eco-tool__label\" for=\"sched-efficiency-t18x\">Charging efficiency<br>(%)<\/label>\n        <input class=\"eco-tool__input\" id=\"sched-efficiency-t18x\" type=\"number\" min=\"50\" max=\"100\" step=\"1\" value=\"90\" inputmode=\"numeric\">\n        <div class=\"eco-tool__hint\">Charging losses are normal.<\/div>\n      <\/div>\n\n    <\/div>\n\n    <div class=\"eco-tool__actions\">\n      <button type=\"button\" class=\"wp-element-button eco-tool__btn\" id=\"sched-calc-btn-t18x\">Calculate<\/button>\n      <button type=\"button\" class=\"wp-element-button eco-tool__btn eco-tool__btn--ghost\" id=\"sched-reset-btn-t18x\">Reset<\/button>\n      <div class=\"eco-tool__error\" id=\"sched-error-t18x\"><\/div>\n    <\/div>\n  <\/form>\n\n  <div class=\"eco-tool__result\" id=\"sched-result-t18x\" hidden>\n    <h3 class=\"eco-tool__subtitle\">Result<\/h3>\n\n    <div class=\"eco-tool__cards\">\n      <div class=\"eco-tool__card\">\n        <div class=\"eco-tool__metric-label\">Energy needed<\/div>\n        <div class=\"eco-tool__metric-value\" id=\"sched-energy-output-t18x\">\u2014<\/div>\n        <div class=\"eco-tool__metric-sub\">Grid electricity needed including charging losses.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__card\">\n        <div class=\"eco-tool__metric-label\">Charging time required<\/div>\n        <div class=\"eco-tool__metric-value\" id=\"sched-time-output-t18x\">\u2014<\/div>\n        <div class=\"eco-tool__metric-sub\">Estimated time needed to reach target.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__card\">\n        <div class=\"eco-tool__metric-label\">Recommended start time<\/div>\n        <div class=\"eco-tool__metric-value\" id=\"sched-start-output-t18x\">\u2014<\/div>\n        <div class=\"eco-tool__metric-sub\">Best simple start time within your window.<\/div>\n      <\/div>\n\n      <div class=\"eco-tool__card\">\n        <div class=\"eco-tool__metric-label\">Schedule status<\/div>\n        <div class=\"eco-tool__metric-value\" id=\"sched-status-output-t18x\">\u2014<\/div>\n        <div class=\"eco-tool__metric-sub\" id=\"sched-status-sub-t18x\">\u2014<\/div>\n      <\/div>\n    <\/div>\n\n    <p class=\"eco-tool__note\">\n      Approximate optimizer only. Real charging schedules depend on your EV, charger limits, smart tariffs, battery temperature, charging curve, and utility rules.\n    <\/p>\n  <\/div>\n\n  <details class=\"eco-tool__details\">\n    <summary class=\"eco-tool__summary\">How we calculate<\/summary>\n    <div class=\"eco-tool__details-body\">\n      <ul class=\"eco-tool__list\">\n        <li>Energy needed = battery size \u00d7 charge difference \u00f7 charging efficiency<\/li>\n        <li>Charging time = grid energy needed \u00f7 charger power<\/li>\n        <li>The optimizer tries to fit charging into the cheap tariff window where possible<\/li>\n        <li>If not enough time is available, it recommends charging as soon as possible<\/li>\n      <\/ul>\n    <\/div>\n  <\/details>\n<\/div>\n\n<style>\n.eco-tool{border:1px solid rgba(0,0,0,.12);border-radius:12px;padding:16px;}\n.eco-tool__header{margin-bottom:12px;}\n.eco-tool__title{margin:0 0 8px;}\n.eco-tool__lead{margin:0;opacity:.9;}\n.eco-tool__form{margin-top:12px;}\n.eco-tool__grid3{display:grid;grid-template-columns:1fr;gap:16px;}\n@media (min-width:860px){.eco-tool__grid3{grid-template-columns:1fr 1fr 1fr;}}\n.eco-tool__field{display:flex;flex-direction:column;gap:6px;}\n.eco-tool__label{font-weight:600;}\n.eco-tool__input{width:100%;height:44px;padding:0 12px;border:1px solid rgba(0,0,0,.20);border-radius:10px;background:#fff;box-sizing:border-box;font:inherit;}\n.eco-tool__hint{font-size:.92em;opacity:.78;min-height:38px;}\n.eco-tool__actions{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-top:16px;}\n.eco-tool__btn{padding:10px 22px;}\n.eco-tool__btn--ghost{background:transparent!important;border:1px solid rgba(0,0,0,.20)!important;}\n.eco-tool__btn--ghost:hover,.eco-tool__btn--ghost:focus{background:rgba(0,0,0,.06)!important;border-color:rgba(0,0,0,.35)!important;}\n.eco-tool__error{min-height:1.2em;font-weight:600;flex:1 1 240px;}\n.eco-tool__result{margin-top:18px;}\n.eco-tool__subtitle{margin:0 0 10px;}\n.eco-tool__cards{display:grid;gap:10px;grid-template-columns:1fr;}\n@media (min-width:860px){.eco-tool__cards{grid-template-columns:1fr 1fr;}}\n.eco-tool__card{border:1px solid rgba(0,0,0,.12);border-radius:12px;padding:12px;}\n.eco-tool__metric-label{opacity:.85;font-weight:600;}\n.eco-tool__metric-value{font-size:1.7em;font-weight:800;margin-top:6px;line-height:1.1;}\n.eco-tool__metric-sub{opacity:.85;margin-top:6px;}\n.eco-tool__note{margin-top:12px;opacity:.9;}\n.eco-tool__details{margin-top:16px;}\n.eco-tool__summary{cursor:pointer;font-weight:700;}\n.eco-tool__details-body{margin-top:10px;}\n.eco-tool__list{margin:0;padding-left:18px;}\n<\/style>\n\n<script>\n(function(){\n  const S = \"t18x\";\n  const el = (id) => document.getElementById(id + \"-\" + S);\n\n  const batteryEl = el(\"sched-battery\");\n  const currentEl = el(\"sched-current\");\n  const targetEl = el(\"sched-target\");\n  const powerEl = el(\"sched-power\");\n  const arrivalEl = el(\"sched-arrival\");\n  const departureEl = el(\"sched-departure\");\n  const offStartEl = el(\"sched-offstart\");\n  const offEndEl = el(\"sched-offend\");\n  const efficiencyEl = el(\"sched-efficiency\");\n\n  const calcBtn = el(\"sched-calc-btn\");\n  const resetBtn = el(\"sched-reset-btn\");\n  const errorEl = el(\"sched-error\");\n  const resultEl = el(\"sched-result\");\n\n  const energyOutput = el(\"sched-energy-output\");\n  const timeOutput = el(\"sched-time-output\");\n  const startOutput = el(\"sched-start-output\");\n  const statusOutput = el(\"sched-status-output\");\n  const statusSub = el(\"sched-status-sub\");\n\n  function setError(msg){ errorEl.textContent = msg || \"\"; }\n\n  function toMinutes(t){\n    const parts = String(t).split(\":\");\n    return Number(parts[0]) * 60 + Number(parts[1]);\n  }\n\n  function fromMinutes(mins){\n    mins = ((Math.round(mins) % 1440) + 1440) % 1440;\n    const h = Math.floor(mins \/ 60);\n    const m = mins % 60;\n    return String(h).padStart(2,\"0\") + \":\" + String(m).padStart(2,\"0\");\n  }\n\n  function windowLength(start,end){\n    return end >= start ? end - start : (1440 - start) + end;\n  }\n\n  function isInsideWindow(time,start,end){\n    if(start <= end) return time >= start && time <= end;\n    return time >= start || time <= end;\n  }\n\n  function calculate(){\n    setError(\"\");\n\n    const battery = Number(batteryEl.value);\n    const current = Number(currentEl.value);\n    const target = Number(targetEl.value);\n    const power = Number(powerEl.value);\n    const efficiency = Number(efficiencyEl.value) \/ 100;\n\n    if(\n      !Number.isFinite(battery) || battery <= 0 ||\n      !Number.isFinite(current) || current < 0 || current >= 100 ||\n      !Number.isFinite(target) || target <= current || target > 100 ||\n      !Number.isFinite(power) || power <= 0 ||\n      !Number.isFinite(efficiency) || efficiency <= 0\n    ){\n      setError(\"Please enter valid values.\");\n      resultEl.hidden = true;\n      return;\n    }\n\n    const arrival = toMinutes(arrivalEl.value);\n    let departure = toMinutes(departureEl.value);\n    const offStart = toMinutes(offStartEl.value);\n    const offEnd = toMinutes(offEndEl.value);\n\n    let availableWindow = departure >= arrival ? departure - arrival : (1440 - arrival) + departure;\n\n    const batteryEnergy = battery * ((target - current) \/ 100);\n    const gridEnergy = batteryEnergy \/ efficiency;\n    const hoursNeeded = gridEnergy \/ power;\n    const minutesNeeded = hoursNeeded * 60;\n\n    const cheapWindow = windowLength(offStart, offEnd);\n\n    let recommendedStart = arrival;\n    let status = \"Charge now\";\n    let sub = \"Not enough cheap-tariff time. Start as soon as the vehicle is plugged in.\";\n\n    const departureAbs = arrival + availableWindow;\n    let offStartAbs = offStart;\n    if(offStartAbs < arrival) offStartAbs += 1440;\n    let offEndAbs = offEnd;\n    if(offEndAbs <= offStart) offEndAbs += 1440;\n    if(offEndAbs < offStartAbs) offEndAbs += 1440;\n\n    const latestCheapStart = offEndAbs - minutesNeeded;\n\n    if(minutesNeeded <= availableWindow){\n      if(minutesNeeded <= cheapWindow &#038;&#038; latestCheapStart >= offStartAbs && latestCheapStart >= arrival && (latestCheapStart + minutesNeeded) <= departureAbs){\n        recommendedStart = Math.max(offStartAbs, latestCheapStart);\n        status = \"Optimized\";\n        sub = \"Charging can fit into the cheaper tariff window.\";\n      } else {\n        recommendedStart = Math.max(arrival, departureAbs - minutesNeeded);\n        status = \"Finish before departure\";\n        sub = \"Charging fits before departure, but may not fully fit inside the cheap tariff window.\";\n      }\n    } else {\n      recommendedStart = arrival;\n      status = \"Not enough time\";\n      sub = \"Your available charging window is too short to reach the target charge.\";\n    }\n\n    energyOutput.textContent = gridEnergy.toLocaleString(undefined,{minimumFractionDigits:1,maximumFractionDigits:1}) + \" kWh\";\n    timeOutput.textContent = hoursNeeded.toLocaleString(undefined,{minimumFractionDigits:1,maximumFractionDigits:1}) + \" hours\";\n    startOutput.textContent = fromMinutes(recommendedStart);\n    statusOutput.textContent = status;\n    statusSub.textContent = sub;\n\n    resultEl.hidden = false;\n  }\n\n  function reset(){\n    setError(\"\");\n    batteryEl.value = \"75\";\n    currentEl.value = \"30\";\n    targetEl.value = \"80\";\n    powerEl.value = \"7.4\";\n    arrivalEl.value = \"18:00\";\n    departureEl.value = \"07:00\";\n    offStartEl.value = \"22:00\";\n    offEndEl.value = \"06:00\";\n    efficiencyEl.value = \"90\";\n    resultEl.hidden = true;\n  }\n\n  calcBtn.addEventListener(\"click\", calculate);\n  resetBtn.addEventListener(\"click\", reset);\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>EV Charging Schedule Optimizer Find the best charging window based on your arrival time, departure time, battery needs, and electricity tariff. Battery size(kWh) Usable EV battery capacity. Current batterylevel (%)&hellip;<\/p>\n","protected":false},"author":25,"featured_media":0,"parent":652,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_sitemap_exclude":false,"_sitemap_priority":"","_sitemap_frequency":"","footnotes":""},"_links":{"self":[{"href":"https:\/\/e-car.day\/index.php?rest_route=\/wp\/v2\/pages\/660"}],"collection":[{"href":"https:\/\/e-car.day\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/e-car.day\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/e-car.day\/index.php?rest_route=\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/e-car.day\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=660"}],"version-history":[{"count":1,"href":"https:\/\/e-car.day\/index.php?rest_route=\/wp\/v2\/pages\/660\/revisions"}],"predecessor-version":[{"id":661,"href":"https:\/\/e-car.day\/index.php?rest_route=\/wp\/v2\/pages\/660\/revisions\/661"}],"up":[{"embeddable":true,"href":"https:\/\/e-car.day\/index.php?rest_route=\/wp\/v2\/pages\/652"}],"wp:attachment":[{"href":"https:\/\/e-car.day\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=660"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}