<?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>Solar on Making Clean Tech</title><link>https://nunrg.eu/tags/solar/</link><description>Recent content in Solar on Making Clean Tech</description><generator>Hugo -- 0.136.5</generator><language>en-us</language><copyright>2024 Franci Kopač</copyright><lastBuildDate>Thu, 20 Mar 2025 12:58:48 +0100</lastBuildDate><atom:link href="https://nunrg.eu/tags/solar/index.xml" rel="self" type="application/rss+xml"/><item><title>Solar System Monitor Using Three Analog Dials On E-paper</title><link>https://nunrg.eu/posts/epaper-servo-gauge/</link><pubDate>Thu, 20 Mar 2025 12:58:48 +0100</pubDate><guid>https://nunrg.eu/posts/epaper-servo-gauge/</guid><description>A solar-system monitor that shows live data on three analog-style dials drawn on an e-paper display, driven by an ESP32.</description><content:encoded><![CDATA[<p>You can support me by <a href="https://medium.com/@francikopa/solar-system-monitor-using-three-analog-dials-on-e-paper-fc45434353f0">reading this article on Medium</a> or
you can buy me a beer <a href="https://paypal.me/FranciKopac?country.x=SI&amp;locale.x=en_US">here</a>.</p>
<h2 id="introduction">Introduction</h2>
<p>Last fall I came across an interesting article in <a href="https://hackaday.com/2024/11/25/e-ink-screen-combined-with-analog-dial-is-epic-win/">Hackaday</a>, where <a href="https://arnweb.nl/gitea/arne/EinkAnalog">Arne van Itersen</a> made an interesting solar power display with an analog gauge and an e-paper screen.</p>
<p>It immediately grabbed my attention because it solves the biggest problem with e-paper displays—they need a few seconds to refresh, making them unsuitable for displaying continuously changing data like solar power. A simple analog needle takes care of that problem but is limited to displaying one thing only. But if you put the needle in front of an e-paper screen, you get continuous power information from the needle. You can then use the e-paper display for displaying things that only change every few minutes, like storage battery level, daily production, and system operation mode.</p>
<p>But using an analog dial from a multimeter seemed a bit fiddly to me, and I thought about how to improve on that. Using a small servo instead would be better, because I could use needles of any size. Controlling the servos is quite simple too, I needed the ESP32 to control the e-paper display anyway. It took a weekend to put together a simple prototype for a one gauge display, which I used for my DIY EV-charger.</p>
<figure>
    <img src="/images/epaper/1semafor.jpg" alt="EV-charger display using a needle over an e-paper display">
    <figcaption>The first try, a 1-gauge display for my EV charger</figcaption>
  </figure>
  
<p>The thing worked like a charm and got me thinking about how to improve it. I was thinking about updating my solar system display for a while now, and this seemed like a good solution.</p>
<h2 id="thinking-about-the-design">Thinking About The Design</h2>
<p>One needle wasn&rsquo;t going to cut it this time—I wanted one for solar power, one for power coming from the grid, and one for the power going into the house. After thinking about it for a while, I decided to put the grid and house power servos on the left and right side of the display. The solar servo would be on the bottom. This provides some spatial logic too—power flows from the grid (left) or solar (bottom) to the house (right). I guess putting the solar need on top could also work, but that didn&rsquo;t look right to me for some reason.</p>
<p>I wanted to put the display outside, where it would be exposed to the elements, so it needed a weatherproof housing. So I had to think a bit on how to make a housing that would be both weatherproof and easy to assemble. It&rsquo;s easy to build a two part shell, but how to design it in a way you can assemble and then disassemble it easily while keeping it watertight? I decided to approach it differently. I designed a mounting plate for the servos and the e-paper display first and gave it a flange on the sides and on the bottom. Then I designed a one-piece housing with a window and a simple top cover. This housing had simple guides to hold the flanges of the mounting plate. The window can be closed using some acrylic glued with silicone to make it weatherproof. The top cover is designed to have rainproof downslopes and only needs a drop of superglue on each side to keep it in place. This makes the assembly and testing really simple, you can do everything with the mounting plate alone.</p>
<figure>
    <img src="/images/epaper/mountplate.jpg" alt="The mounting plate with installed servos, e-paper display, and connected ESP32">
    <figcaption>The assembled mounting plate, ready for testing, only the needles are missing</figcaption>
  </figure>
  
<h2 id="the-software">The Software</h2>
<p>I&rsquo;m used to Arduino, so this is what I used. E-paper in Arduino is IMO best used with the GxEPD2 library, which includes the Adafruit GFX functions, the servos are controlled using the Servo library, data exchange is done using Adafruit MQTT, and network connectivity uses WiFi.</p>
<p>The program is subscribed to several MQTT topics, containing the values for grid power, house power, solar power, solar production, battery level, and system mode. Each of these topics is linked to a callback function that triggers on topic updates. The callback functions for grid, house and solar power all move the respective servo needles. The callbacks for battery level and solar production only update the relevant global variables. Screen refresh is only directly triggered by a system mode topic change or every 10 minutes, but this updates the display with the latest data stored in the globals.</p>
<p>Startup makes a full sweep of all the needles, serving as a kind of servo calibration check, then starts the main loop. The main loop is really short and only keeps the MQTT connection alive and resets the whole thing if Wi-Fi drops.</p>
<h3 id="getting-the-data-to-the-topics">Getting the Data To the Topics</h3>
<p>The one remaining job on the software side was to get the data from my solar system to the MQTT topics. The solar system is connected to my Home Assistant installation, so it was really easy to set up some automations that publish the relevant data to MQTT topics when the relevant sensor states change. I used state changes for triggers and the MQTT Publish service to send the data to the MQTT topic. I already had a MQTT broker set up for my other projects, so I just used that one.</p>
<h2 id="build">Build</h2>
<p>Once I was satisfied with the results, it was plain sailing:</p>
<ul>
<li>3D-print the enclosure using ABS</li>
<li>Cut the acrylic to size and glue it to the enclosure using some silicone glue</li>
<li>Drill a hole for the power cable on the appropriate spot, then use some mounting glue to fix the enclosure to the wall</li>
<li>Connect the power and insert the mounting plate in the housing.</li>
</ul>
<figure>
    <img src="/images/epaper/3semafor.jpg" alt="The finished and closed enclosure">
    <figcaption>The end product on a sunny day while charging my EV. Note to self—it&#39;s really easy to scratch acrylic with screw heads 🤦‍♂️</figcaption>
  </figure>
  
<p>You can find all the relevant code and files on <a href="https://github.com/FrenkK/servo-epaper-gauge">Github</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>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></channel></rss>