The best part of working at VIA? Its people. Twice a year, our Montreal and Somerville offices get together for what we call the “All Hands”. All Hands are essential to our company culture: they offer an uninterrupted time of sharing team wins, solving project challenges, and planning for the next big thing. In a few short weeks, we will be recharging our batteries and getting ready to tackle 2020!
The International Energy Agency projects that 30% of all vehicles will be electric vehicles (EV) by 2030. This transition, at the intersection of electric power and mobility, combined with increased generation from renewable resources has the potential to significantly reduce greenhouse gas emissions in the years ahead. To make this happen, utilities who operate the distribution network need to understand how this new demand for electricity will affect smart grid assets. Our primary job at VIA is to help utilities navigate these shifts by understanding their data and fostering collaboration through our Global Data Asset Collaborative™ (GDAC™) program. As an example, VIA recently kicked off our first GDAC™ by focusing on transformers. Through this GDAC™, we are beginning to see that transformers are stressed by the switch to EVs and our focus will be on helping utilities find ways to keep these assets healthy over the coming years.
There are at least two things that make charging an EV different than, say, running a central AC unit. First, the power that needs to be delivered to an EV is around 20kW, which is four or five times the power required for a typical central AC unit, which ranges from 3-5kW. A “short-range” charge to power the EV so that its owner can commute could require around 40kWh, thus a “slow-charge” for a “short-range” car requires about two hours of charging. Powering large fleets of EVs will clearly require extending the capacity of current electricity distribution networks.
The second issue that makes charging an EV different is timing. The timing of EV charging events changes the daily load profile of the home, workplace, and in urban centers equipped with networks of charging stations. Transformers are generally able to run past their rated capacity so long as they are given ample time to cool overnight. That is changing as commuters return home after work to charge their vehicles, never allowing transformers that time to cool down, which can cause them to malfunction and in extreme cases, explode. EV charging events, because they demand so much power so quickly from the grid, can lead to shifts in voltages along the distribution network. This leads to wear and tear on tap changers and other voltage regulation mechanisms.
Utility asset managers need to understand which transformers in their fleet are most at risk as EV penetration increases. A recent study by researchers at Ohio State University illustrates what needs to be done to understand the effects EVs have on transformers and voltage regulators (“An Integrated Algorithm for Evaluating Plug-in Electric Vehicle’s Impact of the State of Power Grid Assets”). The authors have studied a representative sample of urban, suburban, and rural areas and tried to answer the question “What would happen to the distribution grid if each home had an EV?” To understand both the total load and the rapid charging behavior, the authors used actual distribution grid topology provided by American Electric Power (AEP) and simulated the behavior of the system as EV charging events are inserted into today’s “baseline” load demand. The authors find that suburban areas are expected to see the greatest stress, as it is assumed that, in urban areas, additional power will be provisioned by specific “fast-charging” stations while the suburban dwellers load will stress the transformers that serve their primary residences. In rural areas, the lower population density typically means that the transformers are not as heavily loaded as in a suburban area. Some authors predict long-term changes in mobility patterns that will increase the number of rideshare services (i.e., Uber). Rideshare cars are typically required to drive all day and would require longer charge times. This corresponds to the most aggressive scenario studied by the authors, in which case they expect insulator degradation to occur after just one year. The results illustrate the socio-technical complexities of planning the future smart grid and the need for detailed studies on how people are expected to use their vehicles.
As a highly-trained problem solver with deep scientific and computing expertise, I’m always hungry for tough problems to solve. There’s no doubt that integrating EVs into the smart grid is a tough problem. More importantly, it is a high-impact socio-technical problem that we as a society need to solve to transition to a greener future. Working together with the world’s largest utilities, VIA is in a position to help solve these problems, a privilege I am grateful for every day I go to work. At VIA, we have a company value, “Love in=Love out” which means that if you love what you are doing, you will do great work. I expect we will do great work in this area, and help our customers navigate the challenges of the EV revolution.
In March, VIA’s Ashley DaSilva, Team Leader, Product Development, was invited to lead a workshop on unit testing for McGill’s Computer Science Graduate Society. The workshop was part of their seminar series: CS Tools and Tricks, which introduces graduate students to topics they may not otherwise explore in depth in their academic programs. Ashley discussed the critical importance of software testing, why developers should embrace unit testing, and when and how to use mocking. She shares her experience with unit testing and a recap of her workshop below.
Learning Never Goes Out of Style
I first learned the importance of software testing in the early days of my theoretical physics Phd program. Back then, most of my coding was limited to scripting. I wrote scripts to model physical systems, analyze data, and visualize results. Over time, I started writing modules to be reused by myself or my colleagues for different projects. The first time I attempted to refactor one of these modules, it broke in unexpected ways, and I spent days tracking down and resolving all the issues.
I’ve grown significantly as a developer since those days, and now lead a product development team at VIA, focused specifically on the Trusted Analytics Chain™ (TAC™). Every day, my team and I build, test, and deploy Docker containers with microservices. This includes Airflow and RabbitMQ for scheduling tasks, Redis as a cache storage, and BigchainDB to host a blockchain. Software testing is critical to each stage of product development, and something we constantly work to improve.
Unit testing is the foundation of VIA’s software testing process, and an essential skill for all of our developers. For example, TAC™ contains several components that all need to communicate with each other. We maintain a list of python scripts that are authorized to run on the system. Components of TAC™ must download this list to verify the checksum of the scripts. If we did not use mocking for the content of the list in the unit tests of these verification functions, then every time the list was updated, the tests would all have to be updated to account for the change. With mocking, we are free to update the list of scripts without affecting the status of the unit tests.
Ready, Set, Resilience!
Clean Architectures in Python by Leonardo Giordani is a great resource for learning more about unit testing and test-driven development. During my workshop at McGill, I presented examples of unit testing and mocking and shared a few exercises for the students to practice on their own. Some of these exercises came from the github repository associated with Giordani’s book. I’ve included some other examples below:
First, let’s look at a snippet of code. The code below shows a DataAnalyzer class. It has a method, get_data, which is a placeholder for however one would want to retrieve the data from an external resource (e.g., a database or an http request). It also has a method,
analyze_data which performs the sum of the items in a list:
class DataAnalyzer: def get_data(self): # Gets data from an external resource pass def analyze_data(self): data = self.get_data() result = sum(data) return result
The code below shows one example of a unit test that uses mocking of the get_data method:
from unittest import mock from calc.analyzer import DataAnalyzer def test_analyzer(): analyzer = DataAnalyzer() with mock.patch("calc.analyzer.DataAnalyzer.get_data", return_value=[1.0, 2.1, 3.5]): result = analyzer.analyze_data() assert result == 6.6
In this example, the unittest.mock.patch will be applied to the method specified as its first argument and return the assigned return value every time that method is called from inside the scope of the patch. A sample list is assigned to the return value of the patch of the get_data method. This list should have the same format as the expected output of the get_data method, which in this case is a list of floating point numbers. Finally, the result of the analyze_data method is checked that it matches the expected value.
Mocking can also be used to check how you handle exceptions:
import pytest from unittest import mock from calc.analyzer import DataAnalyzer def test_analyzer_connection_error(): analyzer = DataAnalyzer() with mock.patch("calc.analyzer.DataAnalyzer.get_data", side_effect=ConnectionError("Could not connect.")): with pytest.raises(ConnectionError): analyzer.analyze_data()
In this example, instead of specifying a return value, there is a side effect. When the specified method is called, the side effect will be executed. In this case, a ConnectionError is raised by the get_data method. Using a side effect is particularly applicable when you have logic in your code that catches and recovers from errors.
I enjoyed leading a thoughtful discussion on unit testing, and fielded some great questions from the students. One that stood out to me was:
“How can developers make sure that their mocks don’t get out of date?”
This is a really important and sometimes tricky topic! At VIA, we know that unit testing is only the first step of software testing. We also use other types of tests, like integration tests or end-to-end tests help identify problems in mocking before our software reaches users. And isolating and resolving problems at that stage is key to setting ourselves up for a successful integration.
Mocking allows the freedom to isolate one particular part of your code and focus your unit tests on that functionality. Ideally, the expected inputs and outputs of the component being mocked are not going to change. This is typically true for external modules that you will use, at least within a particular major release of the software. However, if you know a software update will cause a change to your internal code base, it is your responsibility to recognize and communicate how that will affect your teammates. That’s why VIA believes that, in addition to testing, strong team communication and values like Learning Never Goes out of Style, Ready, Set, Resilience!, and Stay Curious are what help us develop and deliver the best iterations of our software to our users.