<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>EV Charging on Making Clean Tech</title><link>https://nunrg.eu/tags/ev-charging/</link><description>Recent content in EV Charging on Making Clean Tech</description><generator>Hugo -- 0.136.5</generator><language>en-us</language><copyright>2024 Franci Kopač</copyright><lastBuildDate>Thu, 31 Oct 2024 18:00:02 +0100</lastBuildDate><atom:link href="https://nunrg.eu/tags/ev-charging/index.xml" rel="self" type="application/rss+xml"/><item><title>EV Charging With Rooftop Solar and Storage</title><link>https://nunrg.eu/posts/ev_charging_solar/</link><pubDate>Thu, 31 Oct 2024 18:00:02 +0100</pubDate><guid>https://nunrg.eu/posts/ev_charging_solar/</guid><description>How to charge an EV with rooftop solar and battery storage, using Home Assistant to maximise self-consumption and cut charging costs.</description><content:encoded><![CDATA[<p>You can support me by <a href="https://medium.com/@francikopa/ev-charging-with-rooftop-solar-and-storage-a0e1e91a7d62">reading this article on Medium</a></p>
<p>In the <a href="https://nunrg.eu/posts/ev_charging_strategies/">previous article</a> we looked at how to rationally charge EVs if you have the option to install your home own charger (<a href="https://en.wikipedia.org/wiki/Charging_station">EVSE</a>). But if you can install your home charger, chances are you can install a rooftop solar system too. And once you have that, a home storage battery is the logical next step.</p>
<p>These two investments finally let you take matters into your own hands and, combined with a heat-pump, effectively decarbonize the majority of your energy use. You will still be dependent on the grid, but instead of being dependent all the time, your dependence shrinks to 3-4 months a year, depending on the sizing and where you live. 🥳</p>
<p>But let&rsquo;s stick to EV charging for now:</p>
<h2 id="the-basic-concept">The Basic Concept</h2>
<p>The best way to explain this is to pretend you are a farmer 😃 Your rooftop solar is a bit like a farm in that it&rsquo;s dependent on the weather. When the sun is shining, your solar plant is producing kilowatts of power. When it&rsquo;s heavily overcast, rainy, or at night, you get next to no production. So when you see the sun shining brightly, charge your car!</p>
<p>This brings all kinds of advantages:</p>
<ul>
<li>The solar energy is effectively free, except for installation costs. You should recover the installation costs in <a href="https://energyefficiency.ie/blog/solar-panels-as-a-financial-investment/">6-7 years</a>.</li>
<li>Any energy you charge from your solar system is carbon neutral, expect for the carbon debt of the installation (I don&rsquo;t like greenwashing, but this happens only once as well and with rational use, it is <a href="https://hcb-solar.com.au/understanding-the-carbon-footprint-of-solar-panels/">negligible in comparison to the avoided emissions</a>).</li>
<li>You are actively contributing to your grid stability. Not only will you be a smaller burden on your grid in general, but with some automation, you can actively act as a good citizen and act to reduce grid load in peak times. Why push power into the grid if you can charge your car instead? Why charge your car with grid power at night if you could have taken advantage of the sun during the day?</li>
</ul>
<figure>
    <img src="/images/EV_charging/solarEVcharger.jpg" alt="Solar EV charging station with storage">
    <figcaption>A simple picture of the concept, credit: Electrek</figcaption>
  </figure>
  
<h2 id="the-setup">The Setup</h2>
<p>The base for this article are a solar system with storage and a controllable car charger (EVSE), connected to a Home Assistant system. I&rsquo;m going to describe a solution with a hybrid inverter, but solutions with a separate power-wall will be similar, depending on the way your power-wall is controlled.</p>
<p>The charging logic will implemented using a Python script in AppDaemon, the rest are normal integrations, automations and entities in Home Assistant.</p>
<h2 id="the-charging-strategy">The Charging Strategy</h2>
<p>There are several things to take care of here:</p>
<ul>
<li>
<p>We need to supervise the total current of the installation to prevent overloads. If you have a 3x 20A home installation, you need to take care not to exceed 20A on any of the phases at any time, regardless of the resulting grid current including solar.</p>
</li>
<li>
<p>We need to prepare separate options at least for green charging and low-cost charging.</p>
<ul>
<li>Green charging will only turn on when you have an excess of energy available and only charge the excess energy without taking any from the grid.</li>
<li>Low-cost charging will charge the car when the energy prices are low using all the available power.</li>
<li>You could also add an &ldquo;express&rdquo; mode which will give you all available power at any time while still ensuring you don&rsquo;t blow any fuses.</li>
</ul>
</li>
<li>
<p>We want to monitor the following at all times:</p>
<ul>
<li>The phase currents. If any one of them is above the installation limit, we need to reduce charging current of the EVSE.</li>
<li>The storage battery charge level. Our strategy will depend on it.</li>
<li>The power coming from/going into the storage battery. This will help us set the EVSE charging power in the green mode.</li>
<li>The power coming from/going into the grid. This will help us avoid the grid utilization penalties.</li>
<li>Status of car connection to the EVSE. This is one of the inputs when deciding whether to turn on charging.</li>
<li>The grid utilization time-slots and limits. This is again helping us to avoid the grid utilization penalties.</li>
<li>Information about consumed energy at the EVSE. This is just to know how much charge was delivered to the car.</li>
</ul>
</li>
</ul>
<h3 id="limiting-currents">Limiting Currents</h3>
<p>This is the simplest part of it all.</p>
<ol>
<li>
<p>We set a current limit, 15A in my case due to limits of the inverter. I could actually go up to 20A, but there are other things to think about outside this scope&hellip;</p>
</li>
<li>
<p>We check the phase currents of the installation every minute.</p>
<p>The interval is important: Too fast and the EVSE does not have the time to respond to current changes. Too slow and we run the risk of blowing a fuse. Fuses work relatively slowly, so you should have about 10 minutes before anything bad happens. But it&rsquo;s better to do it as fast as your car can follow. You see, when the car charger sets the current, it basically tells your car what the maximum current it can take from the EVSE. The on-board charger of the car (OBC) will then honor this limit with a certain delay depending on the manufacturer. But one minute should be ok for most cars.</p>
</li>
<li>
<p>If any of the phase currents is above the limit, we:</p>
<ol>
<li>Calculate the excess current. E.g. if we set the limit to 15A and the biggest phase current is 18A, the excess is 3A.</li>
<li>Then we check the EVSE set curent (e.g. 10A) and subtract the excess (3A) to get the needed current setting (7A).</li>
<li>Most cars can only charge with a minimum of 6A. So if the new current setting is lower than that, we need to turn off the EVSE for a while (e.g. 5 minutes). This will give the fuses some time to cool down.</li>
<li>If limit is over minimum, we set the new current limit (7A) on the EVSE.</li>
</ol>
</li>
<li>
<p>Conversely, if all the phase currents are well below the limit (more than a tolerance we set, normally just the setting resolution, i.e. 1A), we do the above steps in the other direction, increasing the EVSE current limit as needed or turning it on if we had to turn it off previously.</p>
</li>
<li>
<p>Rinse and repeat forever.</p>
</li>
</ol>
<p>This process needs to have an absolute top priority, because it is the only part that can cause problems with our installation. Any strategy we implement will be using it.</p>
<h4 id="example-code">Example Code</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">currentControl</span>(self, limit):    
</span></span><span style="display:flex;"><span>    headroom <span style="color:#f92672">=</span> limit <span style="color:#f92672">+</span> CURRENT_TOLERANCE <span style="color:#f92672">-</span> INSTALLATION_MAXIMUM
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> headroom <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">0</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">#Current too high, calculate wanted charging current to compensate</span>
</span></span><span style="display:flex;"><span>      wanted_current <span style="color:#f92672">=</span> int(self<span style="color:#f92672">.</span>set_current <span style="color:#f92672">+</span> int(headroom))
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">if</span> wanted_current <span style="color:#f92672">&gt;=</span> MIN_CHARGE_CURRENT:
</span></span><span style="display:flex;"><span>        self<span style="color:#f92672">.</span>setEVSE(wanted_current)
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">elif</span> <span style="color:#f92672">not</span> self<span style="color:#f92672">.</span>powerOff:
</span></span><span style="display:flex;"><span>        <span style="color:#75715e"># Turn off to cool off if no headroom</span>
</span></span><span style="display:flex;"><span>        self<span style="color:#f92672">.</span>powerOff <span style="color:#f92672">=</span> <span style="color:#66d9ef">True</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">elif</span> headroom <span style="color:#f92672">&gt;</span> CURRENT_TOLERANCE:
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">#Current too low, calculate wanted charging current to compensate</span>
</span></span><span style="display:flex;"><span>      wanted_current <span style="color:#f92672">=</span> int(self<span style="color:#f92672">.</span>set_current <span style="color:#f92672">+</span> headroom)
</span></span><span style="display:flex;"><span>      self<span style="color:#f92672">.</span>setEVSE(wanted_current)
</span></span></code></pre></div><p><em>This function will be called every minute, regardless of the chosen charging mode, as long as charging is active.</em></p>
<h3 id="green-charging">Green Charging</h3>
<p>Now that the current limiting is out of the way, we can start thinking about green charging.</p>
<p>The first thing to consider is whether the storage battery is at least partially charged. It will act as our buffer when setting the charging power, taking or receiving any power we will not be able to fully compensate by setting the charger current. The storage battery voltage is not an exact measurement of charge level, but close enough. So I simply decided on the lower storage battery voltage limit to enable green charging, corresponding to about 20% of it&rsquo;s capacity. I also set a hysteresis so the charging does not turn on/off repeatedly when we are near the limit. And the charging power near the limit is minimal to avoid spikes.</p>
<p>Next we must take care of proper turning on and off of the car charger. We do this by looking at the car connection status of the charger (in my case 1 means nothing is connected, 2 means connected but not charging, 3 means connected and charging). If the car is connected, but not charging, we should turn on the charger. If the car is not corrected, we should turn it off.</p>
<p>Most importantly, we need to look at the power being charged to the storage battery. This is effectively the excess solar power available and we should charge the car with it. The approach I took is simple, but works well: If the excess power exceeds a certain value (1A of charging current, i.e. 690W + losses), increase the charging current by 1A. If the excess power drops below zero (i.e. we are draining the storage battery), decrease the charging current by 1A. This approach is really simple, but it also helps to smooth out spikes that happen in the solar system due to e.g. clouds shifting quickly.</p>
<p>If you were careful, you might wonder how this works together with the current limiting. For simplicity I decided to adapt the current limiting function to take two values, the current control maximum and the charging logic maximum resulting from excess power.</p>
<p>Finally, I think it&rsquo;s useful to try to speed up the charging when the sun is plentiful. So if the storage battery is more than half-full, I simply charge with full power until it gets down to half-full. This makes the charging faster.</p>
<h4 id="example-code-1">Example Code</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">doGreenCharge</span>(self):
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Set current to minimum at start of charge, only start if voltage high</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># enough, only start if enough headroom</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> self<span style="color:#f92672">.</span>battery_voltage <span style="color:#f92672">&gt;</span> (LOW_BATTERY_LIMIT <span style="color:#f92672">+</span> VOLTAGE_HYSTERESIS):
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">if</span> (self<span style="color:#f92672">.</span>vehicle_state <span style="color:#f92672">==</span> <span style="color:#ae81ff">2</span>) <span style="color:#f92672">and</span> ((MAX_INVERTER_CURRENT <span style="color:#f92672">-</span> self<span style="color:#f92672">.</span>highest_inverter_current) <span style="color:#f92672">&gt;=</span> MIN_CHARGE_CURRENT):
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (self<span style="color:#f92672">.</span>set_current <span style="color:#f92672">==</span> <span style="color:#ae81ff">0</span>) <span style="color:#f92672">or</span> (self<span style="color:#f92672">.</span>set_current <span style="color:#f92672">&gt;</span> MIN_CHARGE_CURRENT):
</span></span><span style="display:flex;"><span>          self<span style="color:#f92672">.</span>setEVSE(MIN_CHARGE_CURRENT)
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># If the battery if full enough, charge</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (self<span style="color:#f92672">.</span>battery_voltage <span style="color:#f92672">&gt;</span> LOW_BATTERY_LIMIT) <span style="color:#f92672">and</span> (self<span style="color:#f92672">.</span>vehicle_state <span style="color:#f92672">==</span> <span style="color:#ae81ff">3</span>):
</span></span><span style="display:flex;"><span>      <span style="color:#75715e"># Do the excess power control</span>
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">if</span> (self<span style="color:#f92672">.</span>battery_power<span style="color:#f92672">&lt;-</span><span style="color:#ae81ff">800</span>) <span style="color:#f92672">and</span> (self<span style="color:#f92672">.</span>greenCurrent<span style="color:#f92672">&gt;</span>MIN_CHARGE_CURRENT):
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (self<span style="color:#f92672">.</span>battery_voltage <span style="color:#f92672">&lt;</span> (LOW_BATTERY_LIMIT <span style="color:#f92672">+</span> VOLTAGE_HYSTERESIS)):
</span></span><span style="display:flex;"><span>          self<span style="color:#f92672">.</span>greenCurrent<span style="color:#f92672">=</span>MIN_CHARGE_CURRENT
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span>          self<span style="color:#f92672">.</span>greenCurrent<span style="color:#f92672">=</span>self<span style="color:#f92672">.</span>greenCurrent<span style="color:#f92672">-</span><span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">elif</span> (self<span style="color:#f92672">.</span>battery_power<span style="color:#f92672">&gt;</span><span style="color:#ae81ff">800</span>) <span style="color:#f92672">and</span> (self<span style="color:#f92672">.</span>greenCurrent<span style="color:#f92672">&lt;</span>MAX_INVERTER_CURRENT):
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (self<span style="color:#f92672">.</span>battery_voltage <span style="color:#f92672">&lt;</span> (LOW_BATTERY_LIMIT <span style="color:#f92672">+</span> VOLTAGE_HYSTERESIS)):
</span></span><span style="display:flex;"><span>          self<span style="color:#f92672">.</span>greenCurrent<span style="color:#f92672">=</span>MIN_CHARGE_CURRENT
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span>          self<span style="color:#f92672">.</span>greenCurrent<span style="color:#f92672">=</span>self<span style="color:#f92672">.</span>greenCurrent<span style="color:#f92672">+</span><span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>      <span style="color:#75715e"># Do full power with full storage battery</span>
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">elif</span> (self<span style="color:#f92672">.</span>battery_voltage <span style="color:#f92672">&gt;</span> HIGH_BATTERY_LIMIT):
</span></span><span style="display:flex;"><span>        self<span style="color:#f92672">.</span>greenCurrent<span style="color:#f92672">=</span>MAX_CHARGE_CURRENT
</span></span><span style="display:flex;"><span>      self<span style="color:#f92672">.</span>currentControl(MAX_INVERTER_CURRENT, self<span style="color:#f92672">.</span>greenCurrent)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">currentControl</span>(self, limit, preference):    
</span></span><span style="display:flex;"><span>    headroom <span style="color:#f92672">=</span> limit <span style="color:#f92672">+</span> CURRENT_TOLERANCE <span style="color:#f92672">-</span> MAX_INVERTER_CURRENT
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> headroom <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">0</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">#Current too high, calculate wanted charging current to compensate</span>
</span></span><span style="display:flex;"><span>      wanted_current <span style="color:#f92672">=</span> int(self<span style="color:#f92672">.</span>set_current <span style="color:#f92672">+</span> int(headroom))
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">if</span> wanted_current <span style="color:#f92672">&gt;=</span> MIN_CHARGE_CURRENT:
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> wanted_current <span style="color:#f92672">&gt;</span> preference:
</span></span><span style="display:flex;"><span>          self<span style="color:#f92672">.</span>setEVSE(preference)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span>          self<span style="color:#f92672">.</span>setEVSE(wanted_current)
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">elif</span> <span style="color:#f92672">not</span> self<span style="color:#f92672">.</span>powerOff:
</span></span><span style="display:flex;"><span>        <span style="color:#75715e"># Turn off to cool off if no headroom</span>
</span></span><span style="display:flex;"><span>        self<span style="color:#f92672">.</span>powerOff <span style="color:#f92672">=</span> <span style="color:#66d9ef">True</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">elif</span> headroom <span style="color:#f92672">&gt;</span> CURRENT_TOLERANCE:
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">#Current too low, calculate wanted charging current to compensate</span>
</span></span><span style="display:flex;"><span>      wanted_current <span style="color:#f92672">=</span> int(self<span style="color:#f92672">.</span>set_current <span style="color:#f92672">+</span> headroom)
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">if</span> wanted_current <span style="color:#f92672">&gt;</span> preference:
</span></span><span style="display:flex;"><span>        self<span style="color:#f92672">.</span>setEVSE(preference)
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span>        self<span style="color:#f92672">.</span>setEVSE(wanted_current)
</span></span></code></pre></div><p><em>Called every minute, calls adapted currentControl function to control the charge current</em></p>
<h2 id="results">Results</h2>
<p>Let&rsquo;s look at a typical mostly sunny day using green charging:</p>
<figure>
    <img src="/images/EV_charging/curves.png" alt="The curves when the system is working">
    <figcaption>The EVSE Charging Power, the Maximum Phase Current and the Storage Battery Level When Charging on a Sunny Day</figcaption>
  </figure>
  
<p>It was a sunny day and I decided to charge up the car in green mode at around 12:20:</p>
<ul>
<li>You can see how the charging power ramps up quickly due to there being so much solar power available at around 12:30, around 8kW.</li>
<li>The power stays almost constant until around 13:20, when another large load (the oven) turns on. This in turn causes the charging power to drop to about 3.5kW due to current limiting until the oven is done. During this time, the system is unable to take all available power (the oven only works on one phase), so the storage battery gets charged up a bit.</li>
<li>At around 13:40 the oven thermostat turns off and the charging power ramps up again. There is another cycle of the oven thermostat with power reducing again due to current control. The oven is finally turned off at about 13:50.</li>
<li>After 14:00 the solar power begins to slowly drop as the afternoon begins. It is clear to see how the system reduces charging power accordingly until about 16:00. There are some short current spikes, but current control takes quick care of them.</li>
<li>At 16:30 the solar power finally drops to a value below minimal charging power and we can finally see a clear trend in the storage battery voltage. The minimal charging power is maintained until the shutoff limit is reached at about 18:15 when the charging shuts off for the day.</li>
</ul>
<p>This was in late October, so I was able to charge only 11.6kWh that day (my personal best was 39,6kWh, almost 2/3 of my Kona), but this is still enough charge to do two errands. It was free in all important aspects—I didn&rsquo;t have to pay anything, it caused no carbon emissions and the power control prevented unnecessary cycling of the storage battery. It is a win-win-win 😀
If I needed more charge that day, I could still simply turn on the cheap charging option and charge to full at night. But it turns out that with my driving, the green option is all I need from about March to about October.</p>
<h2 id="what-if-you-dont-have-storage">What If You Don&rsquo;t Have Storage?</h2>
<p>This same approach would still work if you didn&rsquo;t have a storage battery in your solar system. Instead of looking at the storage battery charging power you would have to look at grid power, but all the rest would be the same.</p>
<p>The only difference is that you would be using the grid as your battery. This means you are not worried about wear on the battery, but you can still be a good citizen and reduce your usage during the maximum grid load times. Sadly, the old-style net-metering with constant energy price does not give you any financial incentive to do that, but I&rsquo;m assuming this will change soon.</p>
<h2 id="conclusion">Conclusion</h2>
<p>This was a short description of the principles of EV charging control in a smart home installation with solar, storage battery, and a car charger. As you can see, home automation is an interesting way to reduce your carbon footprint, save energy (costs), and reduce grid load.</p>
<p>To keep thing simple, I did not discuss the grid utilization limit handling here. If there is interest, I&rsquo;ll write a separate article about that.</p>
<p>The code examples are only snippets and intended as an illustration of principle. If you are interested in details, add a comment below and let&rsquo;s discuss!</p>
<p>If you found this article useful, you can buy me a beer <a href="https://paypal.me/FranciKopac?country.x=SI&amp;locale.x=en_US">here</a>.</p>
]]></content:encoded></item><item><title>EV Charging Constraints and Strategies</title><link>https://nunrg.eu/posts/ev_charging_strategies/</link><pubDate>Sun, 27 Oct 2024 08:53:00 +0100</pubDate><guid>https://nunrg.eu/posts/ev_charging_strategies/</guid><description>The technical and economic constraints of EV charging, and practical strategies to charge cheaper, smarter and more sustainably.</description><content:encoded><![CDATA[<p>You can support me by <a href="https://medium.com/@francikopa/ev-charging-constraints-and-strategies-bf8a11e4f7d7">reading this article on Medium</a></p>
<p>Charging an EV can be really straightforward—have a charger (EVSE) installed, plug the car in and wait until the battery is full. But there is a lot more to it than that—the technical constraints, the varying costs, the desire for sustainability all play a role.</p>
<figure>
    <img src="/images/EV_charging/evplugged.jpg" alt="An EV Plugged Into a Home Charger">
    <figcaption>Looks simple, doesn&#39;t it? (Picture credit: CarPro)</figcaption>
  </figure>
  
<h2 id="technical-constraints">Technical Constraints</h2>
<h3 id="grid-connection-capacity">Grid Connection Capacity</h3>
<p>Many European single-family houses will have a hard limit on on grid connection capacity. For my own home this amounts to 230V, 3-phase, 20A per phase, i.e. 13.8kVA. Plug in any more than that and the distribution fuse blows, leaving you in the dark with an expensive addition to your next electrical bill.</p>
<p>The usual car chargers (EVSE) for family homes in Europe will have a 3x 16A (11kW) charging capacity. This is enough to charge a car at home, but it&rsquo;s not much more than the grid connection capacity of my house. So if the charger is dumb and I try to charge my car while baking some cookies, the combined current on one phase will shoot to 16A (charger) + 8A (oven) = 24 A and I&rsquo;m going to end up in the dark, with an empty battery and no cookies 🫠</p>
<h4 id="solutions">Solutions</h4>
<h5 id="buy-more-capacity">Buy More Capacity</h5>
<p>The old way of solving this would be to install bigger distribution fuses, but this is not an optimal solution and it will be expensive:</p>
<ul>
<li>Your monthly capacity cost will be bigger.</li>
<li>You might have to rewire a part of your house wiring for bigger current.</li>
<li>Depending on the utilization of the transformer in your neighborhood, you might not get the extra capacity even if you are willing to pay for it.</li>
<li>You will be paying for mostly unused capacity.</li>
</ul>
<h5 id="use-a-smart-charger">Use a Smart Charger</h5>
<p>A much better solution is to simply look at the current you are taking from the grid and take action when it exceeds the limit.</p>
<p>You can do this manually to some extent, you just need to be the nagging presence that scolds anyone who even thinks about turning on any big load while you charge your car. This should also immensely improve your relationships! 🤪</p>
<p>A much better solution is to automate this. It&rsquo;s called &ldquo;dynamic charging&rdquo; and most modern home charging stations are able to do it at least to some extent. It works like this: You have a current meter installed on the main electrical connection to your home and a mechanism of some sort regularly checks the load. If the load exceeds your limit, this mechanism (a smart home automation or a function of the charger itself) commands to charger to temporarily reduce the charging current until everything is back to normal. Your car will charge a bit slower sometimes, but you get to eat your cookies, stay warm and keep the lights on. 😃</p>
<p>These days, you can buy an off the shelf home car charger with dynamic charging support and <a href="https://www.carplug.eu/wallbox">there are a lot of models available</a>. But if you are interested in DIY solutions, I wrote an article <a href="https://nunrg.eu/posts/example_diy_charging_point/">about building one yourself</a>.</p>
<h2 id="varying-costs">Varying Costs</h2>
<h3 id="time-based-energy-costs">Time-Based Energy Costs</h3>
<p>Depending on where you live, the cost of electric energy will vary through the day. Where I live, daytime electrical energy is about 50% more expensive, so charging your car will be much cheaper at night and on weekends here.</p>
<h3 id="grid-utilization-costs">Grid Utilization Costs</h3>
<p>Depending on where you live, you might have time-slot based grid utilization costs charged extra. We just got these added to our system and they can make a major difference, a couple hundred Euro or more per year.</p>
<p>It works like this: you choose a connection capacity for each time slot and pay an upfront fixed cost for that. The busy time-slots (during office hours and daytime in winter) are really expensive per kilowatt, so it makes sense to book just enough capacity during the expensive time-slots and all the available capacity during the cheap ones. But there is a catch: if you don&rsquo;t book enough capacity, you will pay a couple of Euros for each 15 minutes you have exceeded it. It will add up quickly!</p>
<p>At first glance, this boils down to the same thing as varying energy costs—charging from grid on off-peak times is cheaper. But this cost basically forces you to really think about your energy use. If you book low capacity during expensive time-slots, you can save hundreds of Euro per year, but if you then blow through those limits, you will pay much more in penalties.</p>
<h3 id="solution">Solution</h3>
<p>Both of these issues can be taken care of manually by being careful about when you decide to charge your car. Of course, having a bit of automation can help a lot, especially with the grid utilization costs and the varying capacities in individual time slots.</p>
<p>A good automated solution will automatically limit the charging power to the capacity limits of the individual time-slots and give you an option to allow or disallow daytime charging. Most cars also have built-in charge schedulers that can help you charge them when the energy is cheaper.</p>
<h2 id="sustainability">Sustainability</h2>
<p>If you care about the climate emergency, you care about carbon intensity of the electric energy you use. In an ideal world, this would have been taken care of by the utilities for you, but we are still a long way from that.</p>
<p>Of course, many utilities are happy to sell you an &ldquo;All Renewables&rdquo; package for your electricity bill, where you pay a little extra so the energy is bought from renewable sources. I support this wholeheartedly, because it gives the energy producers the right incentives to build more renewables. On the other hand, we have to be realistic and acknowledge that you are always consuming electric energy with the average carbon intensity your grid is producing at any given time. There is no way to select for less-carbon intensive electrons, unfortunately 😞</p>
<p>This means you must think about the energy mix in your area and this is something your utility is compelled by law to report transparently. You should get a diagram showing the percentages of energy that come from coal, natural gas, nuclear, solar, hydro, wind etc with all your electricity bills.</p>
<figure>
    <img src="/images/EV_charging/energy_mix.png" alt="Energy Mix in Slovenia in 2023">
    <figcaption>The Energy Mix in Slovenia in 2023, credit SURS</figcaption>
  </figure>
  
<p>But keep in mind, this mix is an average and the actual values vary:</p>
<ul>
<li><strong>Depending on time of day:</strong> If you have a big nuclear backbone, like my country does, you will be consuming mostly nuclear at night, which is low carbon. If you don&rsquo;t, the cheaper night-time energy will probably have a much bigger carbon footprint, coming from coal and natural gas. But some countries have a lot of hydro&hellip;</li>
<li><strong>Depending on the weather:</strong> If your country has a lot of solar, daytime electricity will be almost carbon free unless the weather is bad. A rainy day can cut solar production by 80% or more.</li>
<li><strong>Then there are the seasons:</strong> Hydroelectric plants produce much more energy when the water is plentiful, e.g. in spring and fall. Solar is less plentiful in winter and the opposite holds for wind power.</li>
</ul>
<p>The good thing is, you don&rsquo;t really have to work all of this out yourself. There are services that will give you a good estimate of current carbon intensity in your area, like <a href="https://www.electricitymaps.com/">Electricity Maps</a>, which also has an API and there is even a Home Assistant integration for it.</p>
<figure>
    <img src="/images/EV_charging/carbon_intensity.png" alt="My Electricity Maps Readout">
    <figcaption>My Electricity Maps Readout</figcaption>
  </figure>
  
<h3 id="solution-1">Solution</h3>
<p>You can do a lot here if you just behave rationally. Find the data and act accordingly. But there is also the potential to automate things using the publicly available services like Electricity Maps mentioned above.</p>
<h2 id="conclusion">Conclusion</h2>
<p>EVs have the potential to strongly reduce your carbon footprint and cost per kilometer driven, if you use them rationally. But this is not trivial and there are many factors to consider.</p>
<p>If you want to do EV-charging right, you need to think at least about:</p>
<ul>
<li>Dynamic charging</li>
<li>Time-based energy costs</li>
<li>Grid utilization costs</li>
<li>The energy mix in your area</li>
<li>The variations of the energy mix because of time of day, weather and seasons</li>
</ul>
<p>Keep in mind that you can still think about your energy mix even if you are not able to charge at home. You will, of course, make sure to keep yourself mobile first, but once you take care of that, you can start thinking about other things like carbon intensity.</p>
<p>To keep this article somewhat manageable, I did not discuss other very important factors, like your driving habits, choosing an efficient car and, most importantly, alternative mobility solutions. But let&rsquo;s face it, these are way more important than any charging strategy and the one thing you should think about at the very beginning. Our dependence on cars is toxic to us and the planet, so the best car is still the one that never got built.</p>
<h2 id="the-second-conclusion">The Second Conclusion</h2>
<p>You may have noticed  I did not mention rooftop solar or home energy storage. This is intentional, for two reasons: Most people do not have rooftop solar systems. And of those that do, only few have storage. I wanted to focus on a regular home owner buying their first EV, trying to help them understand the potential and behave rationally, both in terms of costs and environmental concerns.</p>
<p>But rooftop solar, especially combined with storage, opens a whole new dimension of options. I explored these in the next article, <a href="https://nunrg.eu/posts/ev_charging_solar/">EV Charging With Rooftop Solar and Storage</a>.</p>
<p>If you found this article useful, you can buy me a beer <a href="https://paypal.me/FranciKopac?country.x=SI&amp;locale.x=en_US">here</a>.</p>
]]></content:encoded></item><item><title>Example DIY EV Charging Point</title><link>https://nunrg.eu/posts/example_diy_charging_point/</link><pubDate>Fri, 27 Oct 2023 00:00:00 +0000</pubDate><guid>https://nunrg.eu/posts/example_diy_charging_point/</guid><description>A complete DIY EV charging point: bill of materials, schematics, ESPHome firmware and code for a simple, safe home EVSE build.</description><content:encoded><![CDATA[<p>Let’s go into details!</p>
<figure>
    <img src="/images/EV_charging/finished.jpg" alt="Finished product">
    <figcaption>What It Might Look Like</figcaption>
  </figure>
  
<p>If you’ve been reading my <a href="https://nunrg.eu/posts/diy_ev_charging/" title="DIY EV Charging">DIY EV Charging Point Basics</a> post, you probably wonder how all the options mentioned might be distilled into a practical DIY project. This post describes a charging point I actually built. I will explain why and how I made the individual choices, list an actual BOM, describe how everything is connected and even give you the configuration files I used in the first version.</p>
<h2 id="design-objectives">Design Objectives</h2>
<h3 id="some-background">Some Background</h3>
<p>I built this charging point for a neighbor friend who recently, after some deliberation, decided to start driving an EV in the best possible way for “beginners”: He bought a used short-range EV he uses as the “second car” to drive to work and do errands (he has a big family, so there are many errands to take care of). This saves him a ton of gas money and the objectively better driving experience is simply the icing on the cake.</p>
<p>Until now, he was using the charging cable he got with the car, but this was slow (only half the available charging power) and he had no handy sockets to plug it in, forcing him to use an extension cord. So we talked and I offered to help him build a proper Type 2 charging point, enabling him to use the full charging power and avoid dealing with the “cable salad”, while having everything properly prepared for the next EV that is sure to come in time. We sat down, talked and decided what to build.</p>
<h3 id="parameters">Parameters</h3>
<ul>
<li>He does not have a smart home solution, so the solution had to be standalone.</li>
<li>We decided it would be best if we installed it on the outside wall of his house, next to his driveway.</li>
<li>To keep the charging point visually clean, we would use a socket, not a cable.</li>
<li>Although his present car only has a one-phase internal charger, we decided to build a full three-phase charging point, since the difference in costs is minimal and we wanted to keep everything future-proof.</li>
<li>With 3x 20A distribution fuses, dynamic current control was a must.</li>
<li>He needs minimal access control, a switch in the house was enough.</li>
<li>There should be some easy way to charge only at night, when energy is cheaper. But there should also be an option to charge at any time to top up the car when needed.</li>
</ul>
<h2 id="design-choices">Design Choices</h2>
<p>After the parameters were set, it was relatively easy to decide on the final solution:</p>
<ul>
<li>I decided to use the <a href="https://github.com/kortas87/simple-evse">SimpleEVSE</a> controller to take care of the SAE J1772 standard signalling and control since I had good experience using it in the past.</li>
<li>I would use a ESPHome controller, connected to the WiFi to control the EVSE controller (current and time control, monitoring).</li>
<li>The charging point would have it’s own weatherproof switchboard on the outside wall, containing the fuse, relay, EVSE controller and the ESPHome controller. The socket would be built right next to it.</li>
<li>He had some space left in an auxiliary switchboard inside the house, so we would put the RCD switch there, so it can also serve as an access control switch to turn off the whole charging point when needed.</li>
<li>We would install a cheap smart electricity meter in the main switchboard to measure the currents on distribution fuses. Since this switchboard is on the other side of the house and wiring an extra data transfer cable to the charging point would be a problem, I decided to read it using a separate ESPHome controller connected to the home WiFi network.</li>
</ul>
<h2 id="the-actual-build">The Actual Build</h2>
<figure>
    <img src="/images/EV_charging/plan.png" alt="Electric diagram">
    <figcaption>The Plans</figcaption>
  </figure>
  
<p>In our case, the system is housed in two small boxes, but if your installation allows, you could connect the energy counter directly to the charge control ESPHome controller, saving yourself one extra ESPHome controller and getting better reliability.</p>
<h3 id="bom">BOM:</h3>
<h4 id="current-supervisor">Current Supervisor:</h4>
<ul>
<li>Wiring box as your situation requires</li>
<li>An energy meter with Modbus interface, e.g. <a href="https://www.ebay.de/itm/384473893449">this one</a> or <a href="https://www.ebay.de/itm/404221985277">this one</a></li>
<li>RS485 to 3.3V converter, e.g. <a href="https://www.ebay.de/itm/295361148016">this</a></li>
<li>ESP8266 or ESP32 module, e.g. <a href="https://www.ebay.de/itm/144123804853">this</a></li>
<li>A 5V power supply</li>
</ul>
<h4 id="charge-control-unit">Charge Control Unit:</h4>
<ul>
<li>Wiring box</li>
<li>RS485 to 3.3V converter, e.g. <a href="https://www.ebay.de/itm/295361148016">this</a></li>
<li>ESP8266 or ESP32 module, e.g. <a href="https://www.ebay.de/itm/144123804853">this</a></li>
<li>12V to 5V DC-DC converter, e.g. <a href="https://www.ebay.de/itm/255283194266">this</a></li>
<li>EVSE DIN controller, buy it <a href="https://shop.gwl.eu/Electric-Car-Chargers-1/EVSE-Kit-V1-1-For-EV-Charging-Station-Cable-Wallbox-Kit-Only.html">here</a>, the have many other parts for this project too</li>
<li>4-pole contactor, like <a href="https://shop.gwl.eu/Electric-Car-Chargers-1/EVSE-AC-Relay-4X40A.html">this one</a></li>
<li>A RCD, type B, like <a href="https://www.ebay.de/itm/293370848371">this one</a></li>
<li>A MCB (fuse), 16A B-type in our case</li>
<li>A 4P T2 surge protecting device (SPD), like <a href="https://www.ebay.de/itm/404534273552">this one</a></li>
<li>A type 2 socket, like <a href="https://shop.gwl.eu/Electric-Car-Chargers-1/EVSE-EV-Connector-EVSE-Mennekes-Type-2-Socket.html">this one</a></li>
</ul>
<h3 id="build-instructions">Build Instructions</h3>
<p>Use the schematic as your guide. Be careful about proper grounding, correct wire and component sizing, weatherproofing, wiring screw torques etc. DIN-rails are your friend.</p>
<p>You should have enough experience with electric projects to be able to build and customize this from the data I provided. If you don’t, it’s likely you are not able to build it safely on your own, so talk to people who understand it better.</p>
<h3 id="example-code-for-the-two-esphome-controllers">Example Code for the Two ESPHome Controllers</h3>
<h4 id="current-supervisor-1">Current Supervisor:</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">esphome</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">name</span>: <span style="color:#ae81ff">stevec</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">esp8266</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">board</span>: <span style="color:#ae81ff">d1_mini</span>
</span></span><span style="display:flex;"><span>  
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Disable logging to be able to use Modbus</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">logger</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">baud_rate</span>: <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">ota</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">wifi</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">networks</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—ssid</span>: <span style="color:#e6db74">&#34;ssid&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">password</span>: <span style="color:#e6db74">&#34;pass&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">web_server</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">port</span>: <span style="color:#ae81ff">80</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">uart</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">id</span>: <span style="color:#ae81ff">mod_bus</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">tx_pin</span>: <span style="color:#ae81ff">GPIO1</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">rx_pin</span>: <span style="color:#ae81ff">GPIO3</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">baud_rate</span>: <span style="color:#ae81ff">9600</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">stop_bits</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">parity</span>: <span style="color:#ae81ff">even</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">modbus</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">id</span>: <span style="color:#ae81ff">modbus_stevec</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">send_wait_time</span>: <span style="color:#ae81ff">200ms</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">flow_control_pin</span>: <span style="color:#ae81ff">GPIO5</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">modbus_controller</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—id</span>: <span style="color:#ae81ff">stevec</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">address</span>: <span style="color:#ae81ff">24</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">modbus_id</span>: <span style="color:#ae81ff">modbus_stevec</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">update_interval</span>: <span style="color:#ae81ff">5s</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">setup_priority</span>: -<span style="color:#ae81ff">10</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">sensor</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">#Template sensor</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">template</span> <span style="color:#75715e">#Max phase current, will be written by lambda</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#e6db74">&#34;TokMax&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">tokmax</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">#Readouts of individual phase currents from the smart meter</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">modbus_controller</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">modbus_controller_id</span>: <span style="color:#ae81ff">stevec</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">tokr</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#e6db74">&#34;TokR&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">address</span>: <span style="color:#ae81ff">0x0008</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">unit_of_measurement</span>: <span style="color:#e6db74">&#34;A&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">register_type</span>: <span style="color:#e6db74">&#34;read&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">value_type</span>: <span style="color:#ae81ff">FP32</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">accuracy_decimals</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">filters</span>:
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">—sliding_window_moving_average</span>:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">window_size</span>: <span style="color:#ae81ff">6</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">modbus_controller</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">modbus_controller_id</span>: <span style="color:#ae81ff">stevec</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">toks</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#e6db74">&#34;TokS&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">address</span>: <span style="color:#ae81ff">0x000A</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">unit_of_measurement</span>: <span style="color:#e6db74">&#34;A&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">register_type</span>: <span style="color:#e6db74">&#34;read&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">value_type</span>: <span style="color:#ae81ff">FP32</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">accuracy_decimals</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">filters</span>:
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">—sliding_window_moving_average</span>:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">window_size</span>: <span style="color:#ae81ff">6</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">modbus_controller</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">modbus_controller_id</span>: <span style="color:#ae81ff">stevec</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">tokt</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#e6db74">&#34;TokT&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">address</span>: <span style="color:#ae81ff">0x000C</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">unit_of_measurement</span>: <span style="color:#e6db74">&#34;A&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">register_type</span>: <span style="color:#e6db74">&#34;read&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">value_type</span>: <span style="color:#ae81ff">FP32</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">accuracy_decimals</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">filters</span>:
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">—sliding_window_moving_average</span>:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">window_size</span>: <span style="color:#ae81ff">6</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">time</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">sntp</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">sntp_time</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">on_time</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#75715e"># Every 10 seconds do readout of max phase current</span>
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">—seconds</span>: <span style="color:#ae81ff">/10</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">then</span>:
</span></span><span style="display:flex;"><span>         <span style="color:#f92672">—lambda</span>: |-<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              id(tokmax).publish_state((id(tokr).state &gt; id(toks).state) ? ((id(tokr).state &gt; id(tokt).state) ? id(tokr).state : id(tokt).state) : ((id(toks).state &gt; id(tokt).state) ? id(toks).state : id(tokt).state));</span>              
</span></span></code></pre></div><p>This is simple: We talk to the Modbus electricity meter every 10 seconds to get the three currents. We do a moving average to keep track of fast current changes. The result (largest average current) is available over HTTP API.</p>
<h4 id="charge-controller">Charge Controller:</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">esphome</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">name</span>: <span style="color:#ae81ff">evse</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">esp8266</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">board</span>: <span style="color:#ae81ff">d1_mini</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Disable logging to be able to use Modbus</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">logger</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">baud_rate</span>: <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">ota</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">http_request</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">useragent</span>: <span style="color:#ae81ff">esphome/ESP8266</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">timeout</span>: <span style="color:#ae81ff">10s</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">esp8266_disable_ssl_support</span>: <span style="color:#66d9ef">yes</span> <span style="color:#75715e">#to prevent OTA filing</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">id</span>: <span style="color:#ae81ff">http_request_data</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">wifi</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">networks</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—ssid</span>: <span style="color:#e6db74">&#34;ssid&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">password</span>: <span style="color:#e6db74">&#34;pass&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">web_server</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">port</span>: <span style="color:#ae81ff">80</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">uart</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">id</span>: <span style="color:#ae81ff">mod_bus</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">tx_pin</span>: <span style="color:#ae81ff">GPIO1</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">rx_pin</span>: <span style="color:#ae81ff">GPIO3</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">baud_rate</span>: <span style="color:#ae81ff">9600</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">modbus</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">id</span>: <span style="color:#ae81ff">modbus_evse</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">modbus_controller</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—id</span>: <span style="color:#ae81ff">evse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">address</span>: <span style="color:#ae81ff">0x01</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">modbus_id</span>: <span style="color:#ae81ff">modbus_evse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">update_interval</span>: <span style="color:#ae81ff">30s</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">setup_priority</span>: -<span style="color:#ae81ff">10</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">sensor</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">template</span> <span style="color:#75715e">#Max phase current, will be written by lambda</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#e6db74">&#34;TokMax&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">tokmax</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">#EVSE sensors</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">modbus_controller</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">modbus_controller_id</span>: <span style="color:#ae81ff">evse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">set_charge_current</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">register_type</span>: <span style="color:#ae81ff">holding</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">address</span>: <span style="color:#ae81ff">1000</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">value_type</span>: <span style="color:#ae81ff">U_WORD</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Set Charge Current</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">unit_of_measurement</span>: <span style="color:#ae81ff">A</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">device_class</span>: <span style="color:#ae81ff">current</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">state_class</span>: <span style="color:#ae81ff">measurement</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">accuracy_decimals</span>: <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">modbus_controller</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">modbus_controller_id</span>: <span style="color:#ae81ff">evse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">vehicle_state</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">register_type</span>: <span style="color:#ae81ff">holding</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">address</span>: <span style="color:#ae81ff">1002</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">value_type</span>: <span style="color:#ae81ff">U_WORD</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Vehicle State</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">accuracy_decimals</span>: <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">modbus_controller</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">modbus_controller_id</span>: <span style="color:#ae81ff">evse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">ctrl_bits</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">register_type</span>: <span style="color:#ae81ff">holding</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">address</span>: <span style="color:#ae81ff">1004</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">value_type</span>: <span style="color:#ae81ff">U_WORD</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Control Bits</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">entity_category</span>: <span style="color:#ae81ff">diagnostic</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">disabled_by_default</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">modbus_controller</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">modbus_controller_id</span>: <span style="color:#ae81ff">evse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">evse_state</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">register_type</span>: <span style="color:#ae81ff">holding</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">address</span>: <span style="color:#ae81ff">1006</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">value_type</span>: <span style="color:#ae81ff">U_WORD</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#ae81ff">EVSE State</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">accuracy_decimals</span>: <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#Manual current setting slider</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">number</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">modbus_controller</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">modbus_controller_id</span>: <span style="color:#ae81ff">evse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">set_charge_current_input</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">address</span>: <span style="color:#ae81ff">1000</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">value_type</span>: <span style="color:#ae81ff">U_WORD</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Set Charge Current (Input)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">unit_of_measurement</span>: <span style="color:#ae81ff">A</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">min_value</span>: <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">max_value</span>: <span style="color:#ae81ff">16</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">step</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">use_write_multiple</span>: <span style="color:#66d9ef">True</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">write_lambda</span>: |-<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">      if (x &gt; 0 &amp;&amp; x &lt; 6) {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        return 6;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">      }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">      return x;</span>      
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#Switch for turning EVSE on or off. Note the negated function: switch on = EVSE off!</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">switch</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">modbus_controller</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">modbus_controller_id</span>: <span style="color:#ae81ff">evse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">disable_charging</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Disable Charging</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">use_write_multiple</span>: <span style="color:#66d9ef">True</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">register_type</span>: <span style="color:#ae81ff">holding</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">address</span>: <span style="color:#ae81ff">2005</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">bitmask</span>: <span style="color:#ae81ff">16384</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#Template binary sensor for enabling/disabling the whole EVSE system, used for time scheduling to reduce electricity costs</span>
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">template</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Enable</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">enable</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">restore_state</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">optimistic</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">turn_on_action</span>:
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">—switch.turn_off</span>: <span style="color:#ae81ff">disable_charging</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">turn_off_action</span>:
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">—switch.turn_on</span>: <span style="color:#ae81ff">disable_charging</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#Readouts and automation</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">time</span>:
</span></span><span style="display:flex;"><span> <span style="color:#f92672">—platform</span>: <span style="color:#ae81ff">sntp</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">id</span>: <span style="color:#ae81ff">sntp_time</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">on_time</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#75715e"># Every 30 seconds do readout of max phase current</span>
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">—seconds</span>: <span style="color:#ae81ff">/30</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">then</span>:
</span></span><span style="display:flex;"><span>         <span style="color:#f92672">—http_request.get</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">url</span>: <span style="color:#ae81ff">http://stevec.local/sensor/tokmax</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">headers</span>:
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">Content-Type</span>: <span style="color:#ae81ff">application/json</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">verify_ssl</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">on_response</span>:
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">then</span>:
</span></span><span style="display:flex;"><span>                 <span style="color:#f92672">—lambda</span>: |-<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                        id(tokmax).publish_state(root[&#34;value&#34;]);
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      });</span>                      
</span></span><span style="display:flex;"><span>      <span style="color:#75715e"># Every 5 minutes do current control</span>
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">—seconds</span>: <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">minutes</span>: <span style="color:#ae81ff">/2</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">then</span>:
</span></span><span style="display:flex;"><span>         <span style="color:#f92672">—lambda</span>: |-<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              //Current limits of system
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              const float max_phase_current=20, max_charge_current=16, min_charge_current=6;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              //Only do current control if EVSE is ON
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              if (!id(disable_charging).state) {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                //Only do current control if max phase current is too high or charge current setting is reduced (plus offset to prevent corrections under 1A, which have no effect)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                if ((id(tokmax).state &gt; (max_phase_current + 0.5))||(id(set_charge_current).state &lt; max_charge_current)) {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  //If max phase current is too high (plus offset)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  if (id(tokmax).state &gt; (max_phase_current + 0.5)) {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                    //If current is low enough to limit properly
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                    if (id(tokmax).state &lt; (max_phase_current + id(set_charge_current).state—min_charge_current)) {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      //Reduce current setting by exactly the excess current
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      auto call = id(set_charge_current_input).make_call();
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      call.set_value(id(set_charge_current).state—(id(tokmax).state-max_phase_current));
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      call.perform();
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                    } else {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      //Turn off EVSE to cool everything off
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      id(disable_charging).turn_on();
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                    }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  } else if (id(set_charge_current).state &lt; max_charge_current) {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                    //Increase current setting by exactly the unused current capacity
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                    if ((id(set_charge_current).state—(id(tokmax).state-max_phase_current)) &lt; max_charge_current) {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      auto call = id(set_charge_current_input).make_call();
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      call.set_value(int (id(set_charge_current).state—(id(tokmax).state-max_phase_current)));
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      call.perform();
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                    } else {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      //Or set maximum charge current
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      auto call = id(set_charge_current_input).make_call();
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      call.set_value(max_charge_current);
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                      call.perform();
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                    }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              }</span>              
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#75715e"># Every 15 minutes turn EVSE back on</span>
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">—seconds</span>: <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">minutes</span>: <span style="color:#ae81ff">/15</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">then</span>:
</span></span><span style="display:flex;"><span>         <span style="color:#f92672">—if</span>:
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">condition</span>:
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">lambda</span>: |-<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                  return id(enable).state;</span>                  
</span></span><span style="display:flex;"><span>              <span style="color:#f92672">then</span>:
</span></span><span style="display:flex;"><span>               <span style="color:#f92672">—switch.turn_off</span>: <span style="color:#ae81ff">disable_charging</span>
</span></span></code></pre></div><p>This is the main functionality. We set up the Modbus communication with the EVSE controller and prepare the necessary variables to control it. My neighbor did not want to have the whole Home Assistant setup, so the control works via a slider in the inbuilt web server.</p>
<p>The control principle is simple – if the average max current exceeds the permitted maximum, the charging current is set to a lover value. E.g. with 20A limit, if the actual phase current is 22A and the set charging current is 16A, the charging current is reduced by 22-20 = 2A, e.g. to 14A. If there is headroom (a big load has disconnected), the charging current is set higher in the same way. This repeats every 5 minutes.</p>
<p>In extreme cases, where the charging current would have to be reduced under 6A (minimum for the EVSE standard), the charging point is turned off until the next 15 minute interval. This should cool off the fuses enough. Keep in mind that normal  fuses should hold a significant overload for tens of minutes (standard requirement is: blow in less than one hour for 45% overload, over one hour for 13% overload).</p>
<p>All that is left is a simple option to turn the whole thing on or off via a switch in the web server or an API call.</p>
<h2 id="final-notes">Final Notes</h2>
<p>This was intended as an illustration of how to build a safe EV charging point with dynamic current control. There are literally thousands of ways how you could go about achieving this, but the general outline will always be the same:</p>
<p><strong>Measure current coming into your home, compare to limit, set charging current, repeat. Turn off EVSE for 15 minutes, if load is too damn high 😉</strong></p>
<p>This could be thought of as trivial, but there is an important point here: if you buy a ready-made charging point, it needs to dynamically control the charging current! If you buy a “dumb” charging point, you are going to be paying for blown fuses at least some of the time and extra power capacity all the time.</p>
<p>If you found this article useful, you can buy me a beer <a href="https://paypal.me/FranciKopac?country.x=SI&amp;locale.x=en_US">here</a>.</p>
]]></content:encoded></item><item><title>DIY EV Charging Point Basics</title><link>https://nunrg.eu/posts/diy_ev_charging/</link><pubDate>Mon, 20 Feb 2023 00:00:00 +0000</pubDate><guid>https://nunrg.eu/posts/diy_ev_charging/</guid><description>How to build your own EV charging point (EVSE): the basics of EV charging, connectors and a simple DIY design for home use.</description><content:encoded><![CDATA[<p>You can support me by <a href="https://medium.com/@francikopa/diy-ev-charging-point-basics-f0f5b32d1695">reading this article on Medium</a></p>
<h2 id="why-diy-an-ev-charging-point">Why DIY an EV-charging Point?</h2>
<ul>
<li>It’s fun to build things yourself 🎉</li>
<li>You can save some money 💰</li>
<li>You have so much freedom: how it looks, how it works, it’s almost entirely up to you 🤓</li>
</ul>
<h3 id="disclaimerdisclaimer"><a href="#disclaimer">Disclaimer</a></h3>
<figure>
    <img src="/images/electrical-safety-warning-sign.png" alt="Electrical safety warning sign">
    <figcaption>Adults only beyond this point!</figcaption>
  </figure>
  
<p>Unless you know how to DIY some serious electrical installations on your own AND have done that before, DO NOT start building a charging point. A short list of things that could go wrong: fire, electrocution, blown mains fuses, blown built-in car charger…</p>
<p><strong>Adults with electrical engineering background only!</strong></p>
<h2 id="what-to-build">What To Build?</h2>
<h3 id="just-a-charging-cable">Just a Charging Cable</h3>
<figure>
    <img src="/images/EV_charging/type1.png" alt="A Type 1 charging cable">
    <figcaption>A Type 1 charging cable, image credit: Metron</figcaption>
  </figure>
  
<p>It’s hard to make a reliable current limiting solution this way, so it’s probably not worth the extra effort – just buy a standard one.</p>
<p>But it can be a worthwhile option if you need to repair a dead charging cable. Just buy a <a href="https://github.com/kortas87/simple-evse/wiki">SimpleEVSE controller</a>, a 2-pole relay, and a power supply and put it in the old charging cable casing. Please don’t forget to put a Type A RCD on the supply side cable to keep it safe – you never know what’s behind a socket you did not install yourself.</p>
<h3 id="a-full-blown-type-2-charging-point">A Full-blown Type 2 Charging Point</h3>
<p>This is where all the options are: current limiting, automation, access control, visual design, cable v. socket, integration, automation…</p>
<h2 id="options">Options</h2>
<h3 id="current-limiting">Current Limiting</h3>
<p>I think it’s not an option, actually. Either:</p>
<ul>
<li>You risk blowing the distribution fuses every time you forget you are charging a car and you turn on an electric oven or another large load for more than a few minutes.</li>
</ul>
<p>Or:</p>
<ul>
<li>
<p>You pay through the nose for bigger distribution fuses.</p>
<p>Where I live, the standard option is 230V, 3x 20A. Most EVs now have 3x 16A or larger built-in charger. This gives you 4 amps of headroom. Any significant appliance like an oven, washing machine, vacuum, cooking plate, microwave, etc. puts you in the danger zone. So, if you want to be sure, you need at least 35A fuses. This is costly for several reasons:</p>
<ul>
<li>
<p>First of all, bigger fuses directly increase your electric bill even before you use any extra power. In EU, the difference will be on the order of several hundred euros per year.</p>
</li>
<li>
<p>You will have to pay for the change and take care of the paperwork.</p>
</li>
<li>
<p>Your existing house connection likely does not have big enough cabling so you need to upgrade this as well.</p>
</li>
<li>
<p>Your local transformer station could already be loaded to the limit and you can’t even get the extra capacity even if you are willing to pay for it.</p>
</li>
</ul>
</li>
</ul>
<p>The downside to current limiting is a slightly more complicated installation and charging will sometimes take a little longer when you have big loads turned on in your house.</p>
<h3 id="cable-or-socket">Cable or Socket?</h3>
<p>My preference is clear: use a socket.</p>
<figure>
    <img src="/images/EV_charging/type2socket.png" alt="Type 2 socket">
    <figcaption>Type 2 socket, image credit: Digitehnika</figcaption>
  </figure>
  
<p><strong>Pros</strong>: It looks cleaner (no “elephant trunk” on your wall), it’s easier to weatherproof, and every EV owner owns a Type 2 charging cable.</p>
<p><strong>Cons</strong>: You have to take the cable out of your car before you plug it in. But when you come home, you usually have to take groceries etc. out of the car anyway, so it’s not a big deal.</p>
<figure>
    <img src="/images/EV_charging/type2cable.png" alt="Type 2 Cable">
    <figcaption>Type 2 charger with connecting cable AKA the Elephant’s Trunk, image credit: Amazon</figcaption>
  </figure>
  
<h3 id="access-control">Access Control</h3>
<figure>
    <img src="/images/EV_charging/access_control.png" alt="RFID Reader">
    <figcaption>RFID Reader</figcaption>
  </figure>
  
<p>I think most people reading this own a house and are thinking about building a charging point of their own in their own driveway or garage. If this is the case, you don’t need access control unless you live in a really rowdy neighborhood. Let’s face it, most people will not park a car in a driveway belonging to someone else, much less hook up a charging cable unless they REALLY need it. Even if they do, this will cost you a few euros at most. If you are in this situation, you can probably afford a few euros – we should look out for each other, when we can.</p>
<p>Nevertheless, if you need access control, it’s quite easy to arrange and you have several options:</p>
<ul>
<li>The standard solution seems to be RFID. This is an easy option to implement, you just need a RFID reader:
<ul>
<li>Most RFID-readers have the option to simply hard wire an output to the device you want to control. In this case, any EVSE controller should have an input pin to control. Just program your reader, connect the output to the controller and you are done.</li>
<li>You could use the <a href="https://github.com/CurtRod/SimpleEVSE-WiFi">SimpleEVSE-Wifi</a> solution – a simple ESP8266 board you can connect your RC522 RFID-Reader to. It takes care of access control and many other things as well.</li>
</ul>
</li>
<li>You could control the charging station via your <a href="https://www.home-assistant.io/">Home Assistant</a> system. A simple switch there can turn your charging point on or off, but you can also do so much more – time control, control according to your photovoltaic plant production, the possibilities are endless.</li>
<li>Just wire a simple key-controlled switch, hooked to the enable input of your EVSE controller.
Install a switch inside your home and connect it to your EVSE controller. It could even be just your RCD switch. Turn on when needed.</li>
</ul>
<h2 id="what-hardware-to-use">What Hardware To Use</h2>
<h3 id="electrical-components">Electrical Components</h3>
<figure>
    <img src="/images/EV_charging/RCD.png" alt="MCBs, RCDs, etc.">
    <figcaption>Image credit: ABB</figcaption>
  </figure>
  
<p>Any charging point needs these at a minimum:</p>
<ul>
<li>
<p><strong>An RCD protection switch, type B.</strong></p>
<p>This is expensive, but important! A regular RCD (type AC) could fail to protect you in case your car charger fails in a way that makes the fault current non-sinusoidal (e.g. leakage on only one leg of the rectifier). A type B RCD is a more expensive, but it will reliably trip for DC fault currents as well, which are unlikely, but possible in case of catastrophic damage of the built-in charger in the EV. It is also required by the relevant standard (IEC 60364-7-722:2018). Current capacity should be equal to or larger to your fuse rating. Trigger current should be according to your country standard (30mA for me).</p>
</li>
<li>
<p><strong>A fuse.</strong></p>
<p>A regular installation fuse with the same nominal current you want the charging point to have, type A or B (no need for starting current protection).</p>
</li>
<li>
<p><strong>A relay.</strong></p>
<p>A relay (or a contactor) that breaks all the phases AND the neutral. E.g. for a 3-phase charging point you need a 4-pole relay. Nominal relay current should be at least 120% of the nominal fuse current. (E.g. for a 16A charging point, use at least a 20A relay.)</p>
</li>
<li>
<p><strong>A surge protection device.</strong></p>
<p>An over-voltage protection device, type 2, 2-pole for 1-phase and 4-pole for 3-phase charging points. If your car is not protected from lightning (e.g. away from the building, no roof, etc.), use T1+T2.</p>
</li>
<li>
<p><strong>An enclosure.</strong></p>
<p>It’s best to put all of these in an enclosure with a DIN rail. If the enclosure is exposed to the elements, it needs at least an IP55 rating. Some people prefer to put their RCD switch inside the house, so they have an easy way to turn off the entire charging point there as a kind of access control.</p>
</li>
<li>
<p><strong>Cable or socket.</strong></p>
<p>Also expensive, but you don’t want to skimp here, since it is subject to wear. I usually put it next to the enclosure and build an extra sturdy bracket for it – it takes some force to plug and unplug the Type 2 cable.</p>
</li>
</ul>
<h3 id="the-evse-controller">The EVSE Controller</h3>
<figure>
    <img src="/images/EV_charging/simpleEVSE.png" alt="The SimpleEVSE controller">
    <figcaption>The SimpleEVSE controller, image credit: GWL</figcaption>
  </figure>
  
<p>You <a href="#disclaimer">could</a> implement everything using a simple ESP8266 board and some peripherals. But unless this is something you dream about doing, I would very much recommend you go modular: Buy a proven EVSE controller to do all the SAE J1772 standard signalling and control (pilot signal, current control, relay control, enable/disable).</p>
<p>A good option is the <a href="https://github.com/kortas87/simple-evse">Simple EVSE open source project</a>. You can build it yourself or buy a built module at <a href="https://shop.gwl.eu/">GWL</a>. I built three chargers using their kit already and can recommend them (they have sockets, cables, relays, etc. too). But there are other options too: <a href="https://github.com/OpenEVSE">OpenEVSE</a>, <a href="https://github.com/sebdehne/DehneEVSE-Firmware">DehneEVSE</a>, <a href="http://www.evse-wifi.de/">smartWB</a>, and others.</p>
<p>You could also buy a ready-made charging point – you can now buy them at hardware stores. But you will a) overpay for the components you get and b) lose a lot of flexibility. Always go open-source when you can, it will save you trouble in the long run (when the supplier decides to stop supporting it).</p>
<h3 id="the-charging-point-controller">The Charging Point Controller</h3>
<p>The EVSE controller will take care of the signalling and turning the relay on or off. But what about current control, access control, automation, supervision, energy metering, cost counting etc.? This is where it gets interesting. You have many options:</p>
<h4 id="no-extra-controller">No Extra Controller</h4>
<p>If you don’t want any of the above options, just build a dumb charging point. You need a RCD, fuse, EVSE controller, relay and a socket/cable. It will work, but read about the options to understand why this may not be a good idea.</p>
<h4 id="ready-made-integrated-solution">Ready Made Integrated Solution</h4>
<p>Some solutions, like OpenEVSE and smartWB, already take care of some of these options. In essence, they contain both the EVSE controller and the charging point controller. But in my opinion the extra cost is not worth it now that we have ESPHome to play with. Just read their githubs and send these awesome guys some beer money via the donation link, they deserve it.</p>
<h4 id="simple-evse-wifihttpsgithubcomcurtrodsimpleevse-wifi"><a href="https://github.com/CurtRod/SimpleEVSE-WiFi">Simple EVSE-WiFi</a></h4>
<p>A simple ESP8266-based solution with an in-built web server for the Simple EVSE charging controller that will take care of:</p>
<ul>
<li>Default functions:
<ul>
<li>Turning the charging point on or off</li>
<li>Setting the charging current</li>
<li>Charge logging</li>
<li>Control of the SimpleEVSE charging controller registers</li>
<li>HTTP API for automation</li>
</ul>
</li>
<li>Optional functions:
<ul>
<li>With added RC522 RFID-Reader:
<ul>
<li>Authentication</li>
<li>User management</li>
</ul>
</li>
<li>With an added S0 or ModBus energy meter:
<ul>
<li>Measuring charging power</li>
<li>Metering charged energy (included in log)</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>You will need to control the current via the API if you want current limiting. This is easily achievable e.g. in Home Assistant, where you probably already have a smart energy meter integrated. Use the REST service integration.</p>
<h4 id="esphomehttpsesphomeio"><a href="https://esphome.io/">ESPHome</a></h4>
<p>A truly versatile solution that works with an ESP8266 or ESP32 board. It is extremely convenient, you simply program your ESP board via USB once and then you can change the configuration any time using OTA via WiFi. You simply change the YAML file and run the upload program.</p>
<p>The magic of ESPHome is it can work standalone very well, but it is also EXTREMELY easy to integrate into Home Assistant. Whatever hardware you choose to integrate into your charging point (energy meter, sensors, RFID, display, buzzers, LEDs, etc.), you simply add to the YAML configuration file using provided integrations. You can then link these directly using automations within ESPHome or indirectly in Home Assistant.</p>
<h2 id="conclusion">Conclusion</h2>
<p>These are some of the options and things you need to know if you want to build a homebrew EV charging point. In the <a href="https://nunrg.eu/posts/example_diy_charging_point/" title="Example DIY EV Charging Point">next post</a>, I present an example solution using ESPHome that includes current limiting and works standalone.</p>
<p>If you found this article useful, you can buy me a beer <a href="https://paypal.me/FranciKopac?country.x=SI&amp;locale.x=en_US">here</a>.</p>
]]></content:encoded></item></channel></rss>