As a new homeowner and dad of two toddlers that leave every light in the house on, I recently switched to Commonwealth Edison’s Hourly Pricing Program, which means I shifted the amount I pay for electricity from a fixed price rate to a variable rate.
Most people pay a fixed rate for the price of electricity. In northern Illinois, it’s 7.2 cents per kilowatt hour (kWh), but it’s different for different parts of the country. Many electric companies now offer the option to switch to a variable rate, which is based on the actual real-time market price of energy.
According to ComEd: “These prices vary from hour to hour and day to day according to the actual market price of power. Higher prices are most likely to occur on weekday afternoons during the summer.” Since my wife and I both work, and the kids are at daycare, we aren’t home when electricity prices are highest. By the time we arrive home in the evening, the demand for electricity has fallen, since factories and businesses have shut down for the day, so prices for electricity are low, and it’s less expensive for us to crank the air conditioning up and turn all the lights on. Take a look at a typical day for electricity prices: June 13th, 2018.
You can see that prices are very low overnight, roughly 2.5 cents per kilowatt hour, but they start rising in the morning as people wake up and start getting ready for work. Prices peak around 2-3pm, since that is the hottest part of the day, and when air conditioners need to work the hardest. Prices fall precipitously at the 6pm hour as factories close and the sun goes down.
The problem is that my wife is a teacher and has summers off, so she keeps the kids home from daycare during the summer. We need to know when we are paying more electricity, so we can reduce our consumption and lower our bill. That’s why I made the High Priced Electricity SMS Alert.
It texts my wife and I when prices rise above 7.2 cents/kWh.
To build, you need four things: Python, a Twilio account, ComEd’s Hourly Pricing API, and the Windows Task Scheduler.
Make sure you have Python
The first thing you need to do is make sure you have the Python interpreter installed on your machine. If you don’t, then you can download here. I used Python 3.6, but any 3.x should work.
Sign up for a Twilio account
If you don’t have an account already, go ahead and create one here. After you’ve signed in to your account, buy a phone number. Make a note of the phone number you’ve bought, your Account SID, and your Auth Token. You’ll need them all later. If you forget to write them down, you can always find them on the Console.
Once you’ve got Python installed and a Twilio account set up, it’s time to write some code!
First, using the shell, make sure you install the Twilio client:
pip install twilio pip install requests
The other two modules you’ll be using (requests and time) come with the standard Python distribution, so they don’t require any special installation.
First, import requests to facilitate communication with the ComEd API. Import time to handle formatting the time for the text message. Import the twilio rest client to communicate with the Twilio API.
import requests import time from twilio.rest import Client
Now, define your Account SID and Auth Token, and instantiate the client helper library:
account_sid = "your account SID" # found in the Twilio Console auth_token = "your Auth Token" # also found in the Twilio Console client = Client(account_sid, auth_token)
Next, you will need to define the address for the ComEd API:
five_min_api = "https://hourlypricing.comed.com/api?type=5minutefeed"
Extract the most up to date data using the requests library. Something to note here is that ComEd’s API returns data in JSON format. Here is a good refresher If you are unfamiliar with JSON.
five_min_api_response = requests.get(five_min_api)
Initialize two variables,
my_price, and set them to zero:
counter = 0 my_price = 0
Make a function that translates the time into a human readable format. The function below returns the current system time into an HH:MM format:
def get_time(): cur_time = (time.strftime('%I:%M')) return cur_time
Next, you’ll want to get the minutes past the hour. This will be useful in the next function:
def get_minutes(): minutes = (time.strftime('%M')) minutes = int(minutes) return minutes
Since your last function determined how many minutes past the hour it is, you also want to know how many increments of 5 that is. (For instance, 10:26 is 5 increments of 5 past the hour, 4:11 is two increments.)
def how_many_fives(): y = 0 for x in range(1,get_minutes()): if x%5 == 0: y = y + 1 return y
Now that you know how many increments past the hour it is, you can determine the current average price. You are going to loop through
x from 0 to the number of 5 minute increments past the hour. On each successive loop, you are going to grab a corresponding price from the API, and add it to a variable called
my_price so that you get an aggregate price. If this is slightly confusing, think of it like this:
If it’s 2:37pm, that is 7 increments of 5 past the hour. (An important note here is that the API considers the :00 time as the previous hour, so the times go from :05 to :00. I point that out, because I would have expected it to go from :00 to :55.) So we will have 7 prices that we add together to make the aggregate price:
for x in range(0,how_many_fives()): agg_price = five_min_api_response.json()[x]['price'] agg_price = float(agg_price) my_price = my_price + agg_price x = x + 1
Finally, we have an aggregate price for the hour. Now, we divide by
x, and we have our hourly average. Simple!
my_price = my_price/x
Since the ComEd website shows the price out to 1 decimal, we should do the same. It’s nicer to look at, and who really needs to see hundredths of a kilowatt hour?
my_price = round(my_price,1)
You were probably wondering why we hadn’t used our
get_time function yet, so now we will:
time_now = get_time()
Now, we format our text message string. I made a variable called
my_msg, which will be the first line of the text message:
my_msg = "ALERT: You may want to turn off some appliances, "
The second part of the text message string is a variable called
hourly_avg, which uses our variables,
hourly_avg = ("the current hourly avg at " + str(time_now) + " is: " \ + str(my_price) + " cents/kWh. ")
We’re almost done with the code! Now you need a number to send your text message to. The format is below, but typically, you’d want this to be your cell phone number:
num_to_text = "415-500-1234"
Your threshold is subjective, and you can set it to whatever you like. I used 7.2 cents per kilowatt hour, because that is the fixed price of electricity where I live in the suburbs of Chicago:
threshold = 7.2
A simple if statement determines whether a text should be sent. If
my_price, or the current hourly price of electricity exceeds my threshold, then send the text:
if my_price > threshold: client.messages.create(num_to_text, body=(my_msg + str(hourly_avg)), from_="+14155001234")
Lastly, define your main function to call your other functions, and your done. Now you have a simple script that will text you when the price of electricity rises above your threshold:
def main(): get_time() get_minutes() how_many_fives() main()
import requests import time from twilio.rest import Client account_sid = "your account SID" auth_token = "your Auth Token" client = Client(account_sid, auth_token) five_min_api = "https://hourlypricing.comed.com/api?type=5minutefeed" five_min_api_response = requests.get(five_min_api) counter = 0 my_price = 0 # Gets the current time in hh:mm format def get_time(): cur_time = (time.strftime('%I:%M')) return cur_time # Gets the minute right now. def get_minutes(): minutes = (time.strftime('%M')) minutes = int(minutes) return minutes # Determines how many increments of 5 have passed this hour. def how_many_fives(): y = 0 for x in range(1,get_minutes()): if x%5 == 0: y = y + 1 return y for x in range(0,how_many_fives()): agg_price = five_min_api_response.json()[x]['price'] agg_price = float(agg_price) my_price = my_price + agg_price x = x + 1 my_price = my_price/x my_price = round(my_price,1) time_now = get_time() my_msg = "ALERT: You may want to turn off some appliances, " hourly_avg = ("the current hourly avg at " + str(time_now) + " is: " \ + str(my_price) + " cents/kWh. ") num_to_text = "415-500-1234" threshold = 7.2 # Task schedule the script to run every 5 minutes, if the price exceeds the threshold, # send the text. if my_price > threshold: client.messages.create(num_to_text, body=(my_msg + str(hourly_avg)), from_="+14155001234") def main(): get_time() get_minutes() how_many_fives() main()
Once you have the code in your editor, and you’ve modified it with your own
from number (All three of which can be found in your Twilio Console),
num_to_text (typically your cell number, or anyone who would need to know when electricity is expensive), and your desired
threshold, it’s time to test.
Execute the script. If successful, you should receive a text message like the below screenshot:
If you received a text message, congratulations, it worked! A troubleshooting note may be beneficial at this point: If you ran the script and did not receive a message, it could be because your threshold currently exceeds the real time price of electricity. Change your
threshold variable to 0, and rerun your script.
You’ve just received a text message, so you know everything is working. But you don’t want to run it just once. You want a vigilant watcher of real time electricity prices that runs on a regular basis, so you need a mechanism to trigger it. Because I use a Windows based laptop, and I was going for the path of least resistance, I set the Windows Task Scheduler to run every five minutes.
If you’re not familiar with the Windows Task Scheduler, here is a helpful link to get you started. The Task Scheduler is basically just an XML macro, that tells your computer what to do and when to do it. Fear not, there is no need to write any XML code to use the Task Scheduler.
To get started with the Task Scheduler, the easiest way to do it is to Press the Windows + R keys on your keyboard to open Run.
When the Run prompt appears, type taskschd.msc in the Open field. Click or tap on OK.
When the Task Scheduler opens up, look on the right side for a section called Actions. Double click on Create Task.
When you double click, it will open up the Task window. On the top of the screenshot below, there are six tabs (General, Triggers, Actions, Conditions, Settings, History (disabled)). You only need to worry about the first three (General, Triggers, Actions).
On the General tab, you need to give your Task a name. I called it the “ComEd High Price Alert.” It will be helpful, but not necessary, to give your task a description.
Click on the Trigger tab. Then click on “New” to add a new trigger. Under Settings, add a One time trigger and add a Start time. I used 8/5/18 at 1:00pm. Your time will vary, and that’s ok.
Under Advanced Settings, check the box that that says Repeat task every, and change the dropdown to 5 minutes. Make sure the duration dropdown is set to Indefinitely. Now make sure to check the Enabled box, and click OK.
I promise that we are almost done! The last thing to do is click on the Actions tab. This is a slightly tricky step, so there is no shame in rereading this part. Click on “New” to add a new action.
Make sure the Action is set to “Start a program.” The Program/script you want to start is your Python interpreter, so make sure your pathway is set appropriately. Mine is “C:\ProgramData\Anaconda3\pythonw.exe”, but yours will likely be different.
Then you need to fill in the Add arguments (optional) piece. Even though it says “optional”, for our purposes it is required. This is the location of your .py script. This was the part that initially gave me the most trouble, so if you get stuck, here is a nice step-by-step aid.
(Troubleshooting tip: If the Action tab is causing you trouble, it may help to remind you that all Python scripts can be started from the Command Line Interface. The Windows Task Scheduler simply automates that.)
Finally, click OK.
There you have it. In less than 100 lines of code, you’ve built yourself a helpful little script that that texts you an alert when the real time price of electricity rises above the threshold you set. The combination of Twilio, Python, and ComEd have helped me shrink my utility bill, hopefully, it will shrink yours as well!
If you want to see the live prices at the source, check out the Live Prices page. The ComEd API feeds are pretty fun to play around with as well, and are very customizable if you are so inclined to modify the code to suit your purposes.