Solar panels run best when there is a lot of sun, I can sell this generated power as the price of energy is high during daytime. The hours I don’t produce power at night or an a cloudy day, I have to use power from the grid, and that costs me money. At night the price of energy is lower, so maybe switch on the washing machine at night?
To profit maximum of my solar panels and earn some money, energy heavy home equipment like my dishwasher, washing machine and drying machine do ideally run at very specific hours. To find these hours yourselves is too much hassle. And I'm not leaving bed at 3 in the morning for just switching on the washing machine... That is what we have IoT for!
What my LinkIt IoT device will do
1) It will be used to download the forecast (cloud cover) and it will calculate my sun up/down times. Based on this data, it can predict what my solar panels will produce in the coming hours.
2) It will be used to download the Kwh prices from my energy company for the current and next day. Based on this data, it can see when I can best sell my energy, and when to consume in the coming hours.
3) This will be visualized on a set of RGB LEDs that will show different colors and brightness levels to represent the downloaded data.
4) Based on these predictions I can decide when to switch on devices I have around the house, all through the IFTTT (If This Then That) service. For my (dumb) washing machine I get a notification and a beep. But the tool will also be able to push a message to my smart washing machine or smart outlets to let it start at the right time.
HardwareWhat is a Hackster project without hardware? So here we go; a device with a tiny computer, lots of blinking lights, OLED screen, beeps and a joystick.
The Bill of Materials
These are the electronics I use:
- Mediatek LinkIt Smart 7688 DUO
- OLED screen (i2c)
- 24x NeoPixel Sticks (with 8 LEDs each)
- 2-axis+select Joystick
- 2x 470 Ohm resistor for the NeoPixel
- 1000uF 16V capacitor for the NeoPixel
- 10k Ohm resistor for the Joystick
- Wires
- 10A 5V adapter
- Piezo buzzer
- Jack connector of 2.1 mm
- Switch for ON/OFF
For the nice frame:
- Ikea Marietorp photo-frame
- Some wood
- Paint (black and white)
And the tools for building:
- Soldering iron
- Drill (various sizes)
- Glue
- Hacksaw
Putting it together
The NeoPixel strips are to be chain-linked. For the display of the graph, they need to be next to each other, each in the same direction to keep an equal distance between the LEDs. That means that all Data-IN pins are at the bottom and the Data-OUT at the top. They will need to be linked together, but I also need some room for gluing it to my frame. I decided to solder short wires to it, that I will join at the back of the photo-frame. To keep it easy, each par that needs to be linked together has the same color.
All GND and V-IN can be linked together in a random order, pick the points where you have space enough. Advice is to not use 1 wire for GND and one for V-IN, the first pixels will draw all power, leaving less power for the last LEDs. This will result in vague colors at the ends. Between PWR and GND, use a capacitor to catch voltage peaks (the 16V is the MAX the capacitor can handle, so use at least 6.3V for this). On the data-wires, use a resistor to limit the current from the Digital pin to the LEDs.
On the Joystick we need a resistor to have a low constant voltage for the Press button. Once we press, voltage will raise, so the LinkIt will trigger an action. If we would not have the resistor, there would be no voltage at all, leaving the PIN in a floating stage. For the move front/back and left/right, there is used an Analog pin that will always have some current.
The OLED is 4 wires, from which 2 are the I2C SDA and SCL, connect them to the corresponding PINs at the LinkIt.
The Piezo buzzer (from an old computer motherboard) can be used with a resistor, but I could not find clear information about the value of the resistor, and some sources even say there is no resistor needed. So I did go for the no-resistor option, knowing that I might need one later on (thus far not needed yet, it sounds BEEEEEEP!).
To hide the wires into the photo-frame, I've not powered the LinkIt through the USB port, but through the PINs. Feed PWR (5V) to the 5V pin, and the GND to GND (sounds logical, but there are circulation many questions about this on the web...)
The photo-frame comes standard from IKEA. But it's not deep enough to hold the electronics and wires. So I did make the frame deeper by adding planks to it. Also to give some depth between the "glass" and the picture of sunset, I did put thin laths, making it really 3D :)
In the side of the frame I've drilled holes to house the power jack, power switch and piezo buzzer.
Powerrrrr! 192 NeoPixels at full brightness consume a lot of power. Although I'm not using the NeoPixels at full brightness, I took a large power-supply. At least some 4A to be used, but more is better here, specially for sunny days (= bright LEDs).
Mediatek LinkIt Smart 7688 DUOAs the tiny computer, I chose the Mediatek LinkIt Smart 7688 DUO (will call it LinkIt from now on). Really this thing is small! In previous projects I worked with Raspberry Pi's; I expected something half the size of that. But when I received the package, it was only the size of a small matchbox. Opening the matchbox, 3/4 of Wit was foam, leaving a really, really, tiny computer.
MCU and MPU
The LinkIt does have 2 processors (DUO... you could have guessed that): the MCU processor for the internet-connected side and the MPU processor for the sensor-connected side. You can reach both through the pinout:
I'm used to write Python code, and as the LinkIt has an MCU that can work with Python, that will be my basis. I hoped that would do all the tricks. But following a webinar from MediaTek, I realized this is not true. The sensors can only be connected to the MPU, which works with Arduino sketches. I learned that my MCU has to talk to the MPU through Firmata. This is a new world for me.
I need to connect my OLED screen through I2C, the NeoPixel on a digital pin, the Joystick on 2 analog and 1 digital (or analog) pin, and the piezo buzzer on an analog pin. From all types something :)
Getting Started with the LinkItThe steps for getting your LinkIt alive are well described in their manual, I recommend to read that. But some steps to give you a good start:
- Plug the USB cable into your Linkit and a computer.
- Your LinkIt will start up in AP mode.
- Connect your computer to the wifi-AP that the LinkIt created.
- Open website for the AP-mode, setup a password, go to the Network tab.
- Fill in the details of your regular internet connected Wifi and restart
- Board is now connected to Wifi on my home network, remember to also connect your computer to the home network again.
- Now open the setup website of your LInkit again, this time you will be in the Connected mode
- Apply firmware upgrade (see the Mediatek website for latest version)
- Device will restart in AP mode, so do all again:
- Connect your computer to the wifi-AP that the LinkIt created.
- Open website for the AP-mode, setup a password, go to the Network tab.
- Fill in the details of your regular internet connected Wifi and restart
- Board is now connected to Wifi on my home network, remember to also connect your computer to the home network again.
- Now open the setup website of your LInkit again, this time you will be in the Connected mode
Connect to your LinkIt
The LinkIt does have an MCU and an MPU. The MCU runs on OpenWRT and can be accessed from the "outside". You can write scripts, upload them and execute things. The MPU is more a closed environment and only accepts compiled Arduino sketches.Connect to board through SSH to do admin and execute commands
- Download PuTTy and install
- Use IP-address, protocol SSH, port 22 and login with root/pwd
- Accept Security Alert
- (Nice add-on: MPuTTy if you have multiple devices in your network.)
Connect to MCU to upload script files
- Download WinSCP and install
- Use IP-address, protocol SCP, port 22 and login with root/pwd
- Accept Security Alert
Connect to MPU to upload Arduino sketches
- Download Arduino IDE and install
- Setup additonal boards by entering these two URLs in the preference screen: http://download.labs.mediatek.com/package_mtk_linkit_smart_7688_index.json,http://download.labs.mediatek.com/package_mtk_linkit_smart_7688_test_index.json
- Select the board in the menu Tools/Board/LinkIt Smart 7688 DUO
- Connect the LinkIt with your computer through USB. It should automatically connect to a serial port. The port is shown in the Arduino IDE, such that you can upload your sketches directly.
For the code we use in this project, some modules and libraries are needed in the Python and Arduino environment.
Install packages in Python
Connect to your LinkIt using PuTTy. Once logged in, you can use PIP to install the needed Python modules by executing:
pip install requests
pip install qrcode
Install packages in OpenWRT
As OpenWRT does contain a stripped down version of Python, not all modules are installed by default, or install with PIP. For my OLED display I need PIL (Python Image Library) or its sibbling PILLOW.
- Go to your LinkIt setup page, click the link for the OpenWRT page at the bottom of your login page
- Login with the same password
- Go to the System tab, and just below that, click Software tab
- First click Update Lists to update the available packages
- In the search-box search for python-imglib and install.
Install modules in Arduino IDE
For the usage of Firmata and FastLED on the Arduino side, we need to install some modules:
- Download the needed library files for FirmataPlus and place the libraries in the Arduino folder (see the wiki from MrYsLab)
- Go to Sketch/Include Library/Manage Libraries and install the FastLED library:
There are some flavors of Firmata, which do in basic form a bridge between Python on the MCU and Arduino on the MPU, passing over data for the analog and digital pins. Hurray, that is what I need for my joystick!
But getting Neopixels working, or an OLED display is some other story. To extend Firmata, I used FirmataPlus and pyMata.
Controlling the Neopixels
The NeoPixels are controlled by the FastLED module, this module takes care of all the timings for signalling the NeoPixels. To send pixel colors to the NeoPixel, I had to extend my Arduino and Python implementation of Firmata. Python will need to be able to send commands to the Arduino to light up the NeoPixels. For each color change, we need a little bit of traffic over the serial connection, more on that later.
To change the code of Firmata, follow this great manual: http://www.instructables.com/id/Going-Beyond-StandardFirmata-Adding-New-Device-Sup/?ALLSTEPS
The Firmata protocol transfers 7 bit data. The max LED value for R/G/B is 255, but that is more than 7 bits. So the integer needs to be split into 2, as otherwise I'm only receiving values with max 127. Solve this by splitting into more parameters at the Python side, and join them together at the Arduino side. This is well explained in the article as LSB and MSB (Least and Most Significant Byte).
Following this guide, I did adjust this part of Firmata at the Arduino side:
/* FASTLED */
#include <FastLED.h>
#define FASTLED_TYPE WS2812
#define FASTLED_PIN_1 5
#define FASTLED_PIN_2 7
#define FASTLED_COLOR_ORDER GRB
#define FASTLED_BRIGHTNESS 96
#define FASTLED_FRAMES_PER_SECOND 120
#define FASTLED_NUM_LEDS 96
CRGB FastLEDs_1[FASTLED_NUM_LEDS];
CRGB FastLEDs_2[FASTLED_NUM_LEDS];
/* FASTLED FIRMATA */
#define FASTLED_DATA 0x74
#define FASTLED_COLOR 0
#define FASTLED_COLOR_BAR 1
#define FASTLED_SHOW 2
#define FASTLED_BRIGHTNESS 3
#define FASTLED_CLEAR_ALL 4
#define FASTLED_CLEAR_BAR 5
#define FASTLED_ALL 7
#define FASTLED_SHOW_NOW 0
#define FASTLED_SHOW_LATER 1
...
void sysexCallback(byte command, byte argc, byte *argv)
{
...
/* FASTLEDS */
case FASTLED_DATA:
{
if (argv[0] == FASTLED_COLOR)
{
int FastLED_X = argv[1];
int FastLED_Y = argv[2];
int FastLED_Red = argv[3] + (argv[4] << 7);
int FastLED_Green = argv[5] + (argv[6] << 7);
int FastLED_Blue = argv[7] + (argv[8] << 7);
int FastLED_Show = argv[9];
if (FastLED_X >= 0 and FastLED_X <= 11) {
FastLEDs_1[(FastLED_X*8)+FastLED_Y].setRGB( FastLED_Red, FastLED_Green, FastLED_Blue);
} else if (FastLED_X >= 12 and FastLED_X <= 23) {
FastLEDs_2[((FastLED_X-12)*8)+FastLED_Y].setRGB( FastLED_Red, FastLED_Green, FastLED_Blue);
}
if (FastLED_Show == FASTLED_SHOW_NOW) {
FastLED.show();
}
}
if (argv[0] == FASTLED_BRIGHTNESS)
{
int FastLED_Bright = argv[1] + (argv[2] << 7);
FastLED.setBrightness(FastLED_Bright);
}
if (argv[0] == FASTLED_SHOW)
{
FastLED.show();
}
if (argv[0] == FASTLED_CLEAR_ALL)
{
FastLED.clear();
FastLED.show();
for (byte i = 0; i < FASTLED_NUM_LEDS; i++) {
FastLEDs_1[i].setRGB( 0, 0, 0);
FastLEDs_2[i].setRGB( 0, 0, 0);
}
FastLED.show();
}
if (argv[0] == FASTLED_CLEAR_BAR)
{
int FastLED_X = argv[1];
for (byte i = 0; i < 8; i++) {
if (FastLED_X >= 0 and FastLED_X <= 11) {
FastLEDs_1[(FastLED_X*8)+i].setRGB( 0, 0, 0);
} else if (FastLED_X >= 12 and FastLED_X <= 23) {
FastLEDs_2[((FastLED_X-12)*8)+i].setRGB( 0, 0, 0);
}
}
FastLED.show();
}
if (argv[0] == FASTLED_ALL)
{
int FastLED_Red = argv[1] + (argv[2] << 7);
int FastLED_Green = argv[3] + (argv[4] << 7);
int FastLED_Blue = argv[5] + (argv[6] << 7);
for (byte i = 0; i < FASTLED_NUM_LEDS; i++) {
FastLEDs_1[i].setRGB( FastLED_Red, FastLED_Green, FastLED_Blue);
FastLEDs_2[i].setRGB( FastLED_Red, FastLED_Green, FastLED_Blue);
}
FastLED.show();
}
while(Serial1.available() > 0) { Serial1.flush(); }
}
break;
}
...
void setup()
{
//Serial.begin(9600);
// to use a port other than Serial, such as Serial1 on an Arduino Leonardo or Mega,
// Call begin(baud) on the alternate serial port and pass it to Firmata to begin like this:
Serial1.begin(57600);
Firmata.begin(Serial1);
while (!Serial1); // wait for serial port to connect. Needed for ATmega32u4-based boards
...
/* FASTLEDS */
// tell FastLED about the LED strip configuration
FastLED.addLeds<FASTLED_TYPE,FASTLED_PIN_1,FASTLED_COLOR_ORDER>(FastLEDs_1, FASTLED_NUM_LEDS);
FastLED.addLeds<FASTLED_TYPE,FASTLED_PIN_2,FASTLED_COLOR_ORDER>(FastLEDs_2, FASTLED_NUM_LEDS);
// set master brightness control
FastLED.setBrightness(FASTLED_BRIGHTNESS);
}
And I did adjust the Firmata module files on the Python side:
#!/usr/bin/python
class PyMata:
...
# FASTLED commands
FASTLED_COLOR = 0
FASTLED_COLOR_BAR = 1
FASTLED_SHOW = 2
FASTLED_BRIGHTNESS = 3
FASTLED_CLEAR_ALL = 4
FASTLED_CLEAR_BAR = 5
FASTLED_TEST = 6
FASTLED_ALL = 7
FASTLED_SHOW_NOW = 0
FASTLED_SHOW_LATER = 1
...
def fastled_color(self, LEDx, LEDy, COLORred, COLORgreen, COLORblue, LEDshow):
data = [self.FASTLED_COLOR, LEDx & 0x7f, LEDy & 0x7f, COLORred & 0x7f, COLORred >> 7, COLORgreen & 0x7f, COLORgreen >> 7, COLORblue & 0x7f, COLORblue >> 7, LEDshow & 0x7f]
self._command_handler.send_sysex(self._command_handler.FASTLED_DATA, data)
def fastled_show(self):
data = [self.FASTLED_SHOW]
self._command_handler.send_sysex(self._command_handler.FASTLED_DATA, data)
def fastled_brightness(self, LEDbrightness):
data = [self.FASTLED_BRIGHTNESS, LEDbrightness & 0x7f, LEDbrightness >> 7]
self._command_handler.send_sysex(self._command_handler.FASTLED_DATA, data)
def fastled_clear_all(self):
data = [self.FASTLED_CLEAR_ALL]
self._command_handler.send_sysex(self._command_handler.FASTLED_DATA, data)
def fastled_clear_bar(self, LEDx):
data = [self.FASTLED_CLEAR_BAR, LEDx & 0x7f]
self._command_handler.send_sysex(self._command_handler.FASTLED_DATA, data)
def fastled_test(self, COLORred, COLORgreen, COLORblue):
data = [self.FASTLED_TEST, COLORred & 0x7f, COLORred >> 7, COLORgreen & 0x7f, COLORgreen >> 7, COLORblue & 0x7f, COLORblue >> 7]
self._command_handler.send_sysex(self._command_handler.FASTLED_DATA, data)
def fastled_all(self, COLORred, COLORgreen, COLORblue):
data = [self.FASTLED_ALL, COLORred & 0x7f, COLORred >> 7, COLORgreen & 0x7f, COLORgreen >> 7, COLORblue & 0x7f, COLORblue >> 7]
self._command_handler.send_sysex(self._command_handler.FASTLED_DATA, data)
So from Python I can now call these as:
#!/usr/bin/python
# NeoPixel to Red:
LedStick = 5
LedPos = 3
UpdateLed =
firmata.fastled_color(LedStick, LedPos, 255, 0, 0, UpdateLed)
While working on the implementation of the NeoPixel control, I had some headaches before getting it working. It turned out that the PIN on the LinkIt I used (D6) is both analog and digital. The code in Firmata is designed to put the pin to analog by default by setting A7 (PIN25). Using digital only pins (D5 & D7) solved my issue.
The data to light up the NeoPixels, is 1 long string of commands delivered to the first LED, who picks off packet 1 and passes on the remainder to the next LED. LED 2 also takes off 1 packet and passes on the remainder to the next LED. And so on, and so on.
My display is build of 24 NeoPixel strips with 8 LEDs each. That is a total of 192 LEDs. The length of the string is getting too long to be transferred at once. So I did split my NeoPixel into 2 packs. FastLED doe control the delivery of the packets, but needs very precise timing for that. So precise that it will disable interrupts and the serial port for a very short time. As the number of LEDs to control is still relatively high, I do see that if I try to send too much traffic through Firmata, that I start missing little pieces. Because of that, there is a lot of time.sleep(0.5) commands in my code, to make sure I'm not missing data while processing the NeoPixel packets.
Controlling the OLED Display
At first I bought a SPI OLED display. But soon I found that it uses too many wires to control through Firmata. New order! This time an I2C version. With FirmataPlus and pyMata, you can control that "easily" by sending the full I2C code over the serial connection; you don't even need to change the FirmataPlus / pyMata code!
It turned out that my ordered screen was not the easy SSD1306 version, but a SH1106 version. No worries, just another type of commands. SSD1306 can handle small commands for specific pieces of the screen, but SH1106 can only get full pages. That means that the amount of data to send for a screen-refresh is a full 64x128 pixels. The normal bytewidth of an I2C connection could handle 32 bytes in one line, but here comes some limitations of the serial Firmata connection. Each byte is 8 pixels wide, so I could do this with 32 lines. But that did give a disturbed image. I ended up with sending 16 bytes in one go.
The code I found at https://github.com/Schrottratte/sh1106 helped me big time. I did apply the needed changes in this module to send the I2C commands to Firmata instead of normal serial, and applied the smaller packet size:
#!/usr/bin/python
from PyMata_bsl.pymata import PyMata
class device(object):
# Base class for OLED driver classes
def __init__(self, firmata, address=0x3C, cmd_mode=0x00, data_mode=0x40):
self.cmd_mode = cmd_mode
self.data_mode = data_mode
self.firmata = firmata
self.addr = address
# Sends a command or sequence of commands through to the device - maximum allowed is 16 bytes in one go.
def command(self, *cmd):
for i in xrange(0, len(cmd), 16):
self.firmata.i2c_write(self.addr, self.cmd_mode, list(cmd[i:i+16]))
# Sends a data byte or sequence of data bytes through to the device - maximum allowed in one transaction is 16 bytes, so if data is larger than this it is sent in chunks.
def data(self, data):
for i in xrange(0, len(data), 16):
self.firmata.i2c_write(self.addr, self.data_mode, list(data[i:i+16]))
So I need to send 64 I2C commands for the actual refresh and some guiding commands. As long as there is no other communication, this goes fairly well, but as soon as serial traffic goes up, the screen becomes sluggish. Remember the timings of packets? Due to the number of I2C commands that need to be send, f that is disturbed, the screen is the first one where you will see the mess.
Receiving input from the Joystick
The joystick is easier: standard Firmata and just listening to analog and digital signals. Only downside for me so far is that Firmata sends ALL analog changes over the serial to Python. When you want very accurate analog metering this is perfectly fine, but I just want to know what direction the joystick is moving to, one click at a time. From the moment I started the forwarding of analog readings, my display became sluggish.
To resolve this, Firmata has a command to lower the number of interrupts, this will limit the number of reads and serial sends on the joystick. This can be called from Python:
#!/usr/bin/python
# (in ms, so this is half a second!)
firmata.set_sampling_interval(250)
Or set at the Arduino side:
unsigned int samplingInterval = 19; // how often to run the main loop (in ms)
To know when the joystick is moving, at start I capture the neutral value. Moving to one of the sides will raise or drop the value. When this is above the threshold if 50, it will recognize an action. Before recording a next action, it will wait to be neutral first.
Piezo buzzer
Last piece of hardware is a Piezo buzzer. This is standard integrated in the Firmata Plus code, so I transferred the same to my PyMata code.
#!/usr/bin/python
# BEEP!
firmata.play_tone(20,0,100,200)
WebserverThe Energy Planner device does only have a little 64x128 pixel sized screen. This is enough for the basic information, but for setting up the IFTTT events and selecting your YR.no city , I decided to create a webserver on the LinkIt. You can reach this on your local network from a computer, tablet or phone in a normal internet browser.
The HTTP protocol on port 80 was already in use, and I have to keep the URL short (see later note), Creating a connection on port :8080 made too many characters. So I decided to go for an HTTPS connection. For HTTPS we need a certificate, and I had one laying around from an Amazon project I did last summer.
Besides hosting all setup features, it does also provide a set of nice detailed graphs. For the graphs I use a JavaScript library called FxCharts; lightweight and easy to implement. It shows the same data as the LEDs do show, but there is no limitation on the 8 LED blocks.
The intermediate between the core processes and the webserver is a SQLite database. Easy to store data in, easy to get data out. For the scale of data I'm using in my local device, this is powerful enough.
First startAt first start, the Energy Planner doesn't know you yet. It will need your location and your IFTTT account first. Both are explained in detail in the next chapters.
Switching ON the Energy Planner does start setting up the Firmata communication, shows a logo on the display and does light up all LEDs in a white color (this does use Red, Green and Blue, so if one is corrupt, you will see colors). And we will hear a BEEP!
In the SQLite database it will check your settings for location and IFTTT account. How to get the YR location and IFTTT account will be covered in the next paragraphs.
If not present, it will show you the URL and a QR code that links to that same URL. And that is why I needed to keep it as short as possible. This makes the QR code smaller in size, such that I can show it bigger on that little screen.
Wouldn't it be great if we can predict the Solar Power Generation? I think it is, so let's continue with that part :)
Sun altitude
For knowing where the sun is, I do use a calculation based on the Latitude and Longitude of the selected YR.no location. If the altitude is positive, it's daytime, otherwise it's night.
I do also gather the data for June 21 and December 21 (longest day depending on your location). Based on the highest sun-position that day, I do calculate the respective sun height of the current hour. Reason is that I expect you installed your solar panels in an ideal way to catch most of the sun in your summer.
This information is stored in the SQLite database.
Weather forecast
To predict the cloud cover, we use the YR.no weather forecast. This is a website from the Norwegian Meteorological Institute and the NRK that does provide detailed forecasts for Europe. And they have a good XML source, that I actually don't use for the recurring data retrieval... In the XML file, there is no Cloud Cover information, but on the website this is available. So back to the good old Screen Scraping! I'm now reading the HTML file, finding the needed table and split off the needed column.
At the Energy Planner local website, select a city that is close to your location:
From now on, the Energy Planner will download your Cloud Cover forecast every 600 seconds (10 minutes). I'll save the Cloud Cover data also in a SQLite database.
Solar magic!
Now comes the first part of magic: calculate the expected solar power for today.
Based on the sun altitude each hour, we know how many LEDs should shine in each bar. Based on the cloud cover, we reduce the number of bright LEDs: assuming there always is a percentage of powergeneration left on cloudy days, I deduct the altitude by 60% of the clouds. As I have 8 LEDs, I use ceiling to beef the figures up to the next round number (integer).
Example: currently there is a 75% of sunshine compared to June 21. 75% on 8 LEDs = 6 (no ceiling needed). There is 40% cloud cover according to YR.no. So I take 65% of 40 = 24% less power generation. Now deduct that 24% from the 75% sunshine = 57% effect. That makes 57 on 8 LEDs = 4.56 => 5 LEDs. So from bottom up, I do light up 5 LEDs as "sunshine", and 1 as "cloud cover". The remaining 2 LEDs are off.
If it's night and there is no sun, a blue LED will be lit.
The calculation, and the LED information is stored in the SQLite database too.
Usually you pay for a fixed Kwh tariff (contract for 1 or 2 or multiple year, or in the Netherlands we have a High (daytime) and Low (night and weekend) tariff. But since recently, there is now a company who charges you a tariff that changes per hour. Idea behind is that this will stimulate to consume in the cheap hours to let you save money. If you have solarpanels, you do sell your generated energy at the price of that hour, at daytime usually mid-level pricing.
Qurrent API
The company that provides their hourly changing tariffs, is Qurrent. Every day around 14:00 they provide the rates for tomorrow. You can see these on their website or in a mobile app. Their source of this data is provided as an API: call a URL and you get data back. If you do that in a browser, you will get XML, if you do that with a Python Request, you'll get JSON.
Recalculating price levels
As I want to show you the prices, readable on an 8 LED, 24 hours bar display, I need to generate something fancy for the eye!
I take 48 hours of data: everything from today (since last midnight), and if available also the data for tomorrow. Then I take the MAX and MIN value of this dataset. As I want to use 3 colors for the price: green/low & orange/medium & red/high, I calculate the difference between MIN and MAX and split that into 3 pieces.
Shine up the LEDs
Next step is calculating the number of LEDs to light up. To make the small price difference still visible, the bottom LED is always used. The other 7 LEDs are spread over the MIN / MAX difference.
All data (price and LED info) is stored in the SQLite database.
With the joystick you can browse through the hourly details and switch between the Solar and Price graphs.
But more important: you can schedule when your devices will be switched ON. For the real action steps, I use IFTTT (see next paragraph). In this step we will select devices that need to be actioned. I can browse through the prices, and from midnight we have a long period of low prices. Ideal for charging my electric car! So at midnight I do select my Car Charger, this will schedule the IFTTT trigger. My washing machine can run at 4 AM, so that it will be ready just before the rising prices at 7 AM (and so that I have something to do when I wake up).
To send commands to all kind of devices, like my washing machine, electric car charger, lamps, or my phone, I integrated this with the IF This Then That (IFTTT) Maker Webhooks. Sounds difficult, but is actually easy: the energy planner sends a command to IFTTT with your key and the name of the maker event.
Example: at midnight I've scheduled to start charging my electric car. Energy Planner will send a message to IFTTT with the event "EP_CarCharger" and 3 custom set parameters. IFTTT will take care of the rest: my Car Charger is linked to a WeMo switch, IFTTT knows that and will tell this switch to go ON. As a confirmation, the EnergyPlanner will sound a BEEP! (your choice of 5)
Bonus 1: there is an hourly message "EP_Hourly" that can send a Notification to the IFTTT app on your smartphone, containing the Kwh price of the hour.
Bonus 2: there is also an hourly message "EP_Hourly_Hue" that does send an HEX color code, so you can link that to let a lamp shine in Green/Orange/Red, you get it?
Before getting started with IFTTT, we will need to provide our local setup website with some details from you.
First setup an event at IFTTT, follow these images to setup an Applet that will send you a notification for your "Dumb Device" (a not to the internet connected device, like your 5 year old washing machine). You will just have to turn the switch manually, so sending a notification to your phone is all we can do today.
Setting up your available IFTTT events can be done on the website:
If you are not using the joystick for some time, the screen will turn into a clock. And of course, the graph animation on the LEDs is just nice to look at too :)
DemonstrationAs you have come thus far, you are for sure interested to see this all coming to life. So here is the video!
Comments