Pretty Solar Graphs

The first step on my solar progress is to get some graphs done, to get an idea of how much energy I can get from my solar panels on an average day. From this I can work out what I can conceivably run from my setup.

Background

Previously, I installed a simple solar setup for testing. This is using an EPEver Tracer1210A solar charge controller, from Tracer. It wasn’t the cheapest, but it had a lot of good reviews (watch out for cheap copied). The other benefit was the fact it had a serial output that talked modbus, or rs485. Intended for official devices, they do provide the protocol to allow third parties to read the system details.

After doing some searching, I discovered Jamin on github who had done some coding and circuit design to get the current details from the charge controller and push the results out to a service called Blynk.

My Project

Overview

This project gave me the starting point for what I wanted to do. My idea was to do this:

Controller -> RS485 -> NodeMCU -> MQTT -> OpenHAB -> InfluxDB -> Grafana

A little bit convoluted, I could probably have pushed straight to a database for logging, and do the graphs in grafana. I decided that pushing via MQTT would allow me to integrate the logging into my OpenHAB system, which would give me the capability to trigger home automation actions depending on the statistics from the charge controller. For example, it makes it very easy to use OpenHAB to send an email if the battery level gets low, and not only that it could turn off some of the load running off the battery as it gets to different levels.

Circuit

The circuit is pretty much a direct copy of what Jamin used, only adapted for a NodeMCU rather than a ESP8266 Mini Dev board.

Bad photo of current system.

Prototype of circuit. Ordered a 5110 LCD to add to it, and will neaten it all up then.

I did look into powering this from the 5V on the serial output of the charge controller, but according to the documentation this can only put out about 50mA of power, which probably won’t be enough to cover the usage by the NodeMCU.

Code

The initial code can be found on my github repository here:

https://github.com/dpoulson/EPSolar

Still a work in progress, but it does the basics so far. Future improvements will allow writing of certain settings, maybe a simple webserver for point in time readings, or an LCD screen.

Logging

So the circuit will transmit the readings over wifi to my central MQTT server, running mosquitto. MQTT is just a simple messaging system when you can subscribe to, or publish to, certain queues.

Readings from the charge controller will be published to set queues on the server, which OpenHAB will be subscribed to, with the following items file:

Number EPSolar_Temp "Temperature [%.2f °C]" { mqtt="<[mymosquitto:EPSolar/1/ctemp:state:default" }

Number EPSolar_BattVolt "Battery Voltage [%.2f V]" { mqtt="<[mymosquitto:EPSolar/1/bvoltage:state:default" }
Number EPSolar_BattRemain "Battery Remaining [%.2f %]" { mqtt="<[mymosquitto:EPSolar/1/bremaining:state:default" }
Number EPSolar_BattTemp "Battery Temp [%.2f °C]" { mqtt="<[mymosquitto:EPSolar/1/btemp:state:default" }

Number EPSolar_LoadPower "Load Power [%.2f W]" { mqtt="<[mymosquitto:EPSolar/1/lpower:state:default" }
Number EPSolar_LoadCurrent "Load Current [%.2f A]" { mqtt="<[mymosquitto:EPSolar/1/lcurrent:state:default" }

Number EPSolar_PVVolt "PV Voltage [%.2f V]" { mqtt="<[mymosquitto:EPSolar/1/pvvoltage:state:default" }
Number EPSolar_PVCurrent "PV Current [%.2f A]" { mqtt="<[mymosquitto:EPSolar/1/pvcurrent:state:default" }
Number EPSolar_PVPower "PV Power [%.2f W]" { mqtt="<[mymosquitto:EPSolar/1/pvpower:state:default" }

Number EPSolar_ChargeCurrent "Battery Charge Current [%.2f A]" { mqtt="<[mymosquitto:EPSolar/1/battChargeCurrent:state:default" }

Number EPSolar_PVVoltMax "PV Voltage MAX (today) [%.2f V]" { mqtt="<[mymosquitto:EPSolar/1/stats_today_pv_volt_max:state:default" }
Number EPSolar_PVVoltMin "PV Voltage MIN (today) [%.2f V]" { mqtt="<[mymosquitto:EPSolar/1/stats_today_pv_volt_min:state:default" }

My OpenHAB system is configured to store persistence data into an InfluxDB server, which is a common setup amongst the OpenHAB community and is well documented. This InfluxDB stores historic data on items in OpenHAB, which is searchable by Grafana. Grafana gives a nice interface to produce all the pretty solar graphs you might want.

Solar Graphs

Using Grafana to get some pretty solar graphs

Pretty Solar Graphs

This makes it really easy to see just what is happening, including the charging states as it you can see the switch from bulk to float charge on the battery voltage. This should allow me to make sure the charging is correct for the Lithium Ion batteries I want to eventually connect.

Solar!

Over the last couple of years I’ve been looking at the feasibility of  getting photovoltaic cells put on the roof of my house. I’ve only got a small amount of roof space seeing as I live in a mid terrace so wasn’t sure if I could get enough panels to make it worth while. A couple of months ago I decided to take the plunge and get a few quotes in. Unfortunately, this is where I met the main hurdle with the whole project. Despite emailing half a dozen companies, I only got two visits to give me a quote, and only one of those actually sent me a quote.

Thankfully I’d done enough research into the technology and rough costs so that I knew the quote I got back was a pretty typical price. The company also seemed to be pretty decent with some good reviews and a good web site. With all that in mind, I decided to go for it and accepted the quote. I was very impressed with how quickly things went. One of the requirements for getting the feed in tariff from the government is to get an Energy Performance Certificate (EPC) and within a few days I’d had the survey done for that and the certificate in my hands. Only a little over a week later the panels were installed, commissioned and my meter was running backwards.

 

Solar install

Solar install

So, what did I actually get installed? All together, 16 panels were squeezed onto my roof across two elevations with 8 on a west facing aspect and then 8 on the south facing which gave me 4kW in total. The installation is fairly straight forward and involves the two arrays of panels going into an inverter which feeds into the main circuit breaker panel. I’ve also installed a full monitoring system that keeps track of power consumed and solar power produced, which I’ll probably write about in another blog post.

The big question however is, is it all worth it? I haven’t been running them for long enough really to give a definitive answer, but from the calculations I’ve done I think the answer is a resounding yes. The feed in tariff is index linked, so will increase over the 20 year lifespan of the panels along with inflation, and it is highly unlikely that the price of electricity is going to go down, all of which means that I should have paid off the panels totally in under 8 years. I can see that number dropping quite a bit too as electric prices increase. Also, the feed in tariff runs for 20 years, but the panels should last even longer than that and are still 80+% efficient after the 20 year mark so should be providing free electricity for many years after the feed in tariff has finished. Over a 20 year period, the initial investment should see a return of over 12% which is so much more than any bank can offer.

If you can afford to get PV installed, I’d definitely recommend it. I’ve already seen a drastic drop in my electric usage and the money is much better installed on my roof than in the bank.

 

Home Monitoring

Over the past few months I’ve been slowly stocking up on all the equipment needed to properly get back into electronics. As I was gathering things together I discovered Arudinos. These are an easy entry into microcontrollers, much simpler in my opinion to PICs, and cheaper than most other developers kits. The fact that they’re open source and open hardware just seals the case. The standard Arudinos are rather nice to work with, but since messing with them on a few mini projects to teach myself about them, I came across a guy who was selling his own custom design, utilising the arduino bootloader and interface, but in a much smaller form factor and inbuilt wireless communications.

These JeeNodes are about the size of a pendrive, and have an inbuilt RF12B wireless module. Along with the nice hardware design, there are also some easy to use libraries, and a great website to accompany them, with lots of nice tutorials, information, and general geekiness.

Home Automation

So, where does home monitoring come into this? One of the addon boards that Jeelabs sell are little room monitoring nodes that detect temperature, humidity, and light level. Add a PIR and you’ve got a motion sensor too. The guy behind the JeeNodes, Jean-Claude Wippler, has done some great work on power consumption meaning that these room nodes can run off a single AA battery for nearly a year. There are about a dozen or so of these nodes now spread across my house, logging into a database, and I’ve done some basic graphs to display the data.

Home Automation

Now I’d also noticed another project using arduinos to monitor electric consumption that was also based on JeeNodes, and reporting back to a central server to log into a database. This got me thinking, could I combine these, and maybe more. The beauty of open source is the fact you can tweak and edit to your hearts content. The fact that both these projects used JeeNodes, and more importantly, the RF12B library from JeeLabs, means that I only need one receiving station and a few small edits to the nodes.

To the transmissions I added a node type to the beginning of the data. This defined whether the node was a room node, power node, or any other future node types I may define. Most of the rest of the code was left untouched, except to assign a node number to each node. That was the easy bit.

Next I needed a receiving station, and some way to get the data it received into a database. For this I once again turned to the JeeNode. Handily, JeeLabs also sell a nice case for the JeeNode, along with a Ethernet add on. This gives me a very small self contained module that simply needs power, and an ethernet connection. Both the energy monitor project, and the room node project had their own code for a base station, and for getting the data into the database. In the best traditions of open source, I have stolen from both these projects and combined my favourite ideas out of both.

The houseNode sits and listens for any broadcasts from any nodes. It knows about the different types of nodes, and the data structure to be expected for those nodes. When a data packet is received then the node type is stripped out, and the rest of the data put into a structure definition depending on the type. Then a JSON structure is constructed, and sent via HTTP POST to a web server. No acknowledgements of data being received are currently sent, but with future expansions that I have in mind, this will be a requirement.

Home Automation Home Automation

The web server will receive the POST command, and basically dump this information into a database. From this database, a front end can draw graphs and report on anything you want. The front end is very much still in construction, but can be viewed at http://home.22balmoralroad.net/

Future developments I am considering are a thermostat node, to control our central heating, and RFID entry/exit nodes to log in and out of the house. The RF12B modules have a limit of 32 addresses, two of which are reserved. However, 30 nodes should be enough for most of my ideas! It does have the other benefits of very low power, very simple, and the JeeLabs library even has encryption built in. Below are the Arduino sketches for each of the nodes.

 

 

Caller ID from Asterisk to all phones, MythTV’s and SqueezeBoxes

Well, I had some spare time and finally got round to getting CallerID sorted on my phones. I’ve had it enabled on the line for a while now, and even had it doing database lookups to display a name on the phone handsets as well as the number, tho’ that broke when I upgraded Asterisk. I have, however, sorted out that problem and expanded everything a little.

Now, when the phone rings, the number is looked up in a database of known numbers, then sent out to all the phone handsets as well as any active MythTV frontend or Squeezebox on the network! If we are watching the TV a box pops up with the time, date, number, and if found, name of the incoming call. Likewise if we are in the library where we can’t actually hear the phone, then the Squeezebox display will change to the name and number and we can decide wether to answer it or not!

All this is done using a feature in Asterisk call AGI, or Asterisk Gateway Interface. This is very similar to CGI scripts found on web pages. AGI scripts are run from the Asterisk dialplan to do various things. In this case the AGI perl script is run and the incoming call number is passed to it. This number is looked up in a database to see if its a known number. Wether it is known or not, the script sets the full CID info in Asterisk.

It then procedes to use a utility call cidbcast that is in the contrib directory of MythTV. This cidbcast sends out a UDP broadcast over the network to any listening machine, in this case the MythTV backend server which has the mythudprelay program running, another one from the MythTV contrib directory. This picks up the broadcast and sends the message to all MythTV frontends using mythtvosd.

Lastly the AGI script connects to the SlimServer which controls all the Squeezeboxes. Talking over the CLI port (9090) on the server it gets a list of all current players and proceeds to send a simple two line display message consisting of the number and name. The majority of this part of the script is a simple cut and paste of the relevant parts of the Squeezebox plugin written by Max Spicer.

All in all this is a fairly simple thing to implement, but is very useful for those as lazy as me!

Script

#!/usr/bin/perl

use DBI;
use IO::Socket;

# MySQL settings for asterisk
my $dbhost = 'localhost';
my $dbuser = 'asterisk';
my $dbpass = 'asterisk';
my $dbname = 'asterisk';

# Slimserver Settings
my $serverAddress = 'mythbe-1';
my $serverPort = 9090;
my $maxVolume = 75;
my $displayTime = 30;
my $debug = 0;

# Mythtv Setting
my $mythxmlfile = '/usr/lib/asterisk/cidbcast.xml';



################
# Get name from mysql for the incoming number
#
$|=1;

#Get the initial data
     my %input;
     while() {
         chomp;
         last unless length($_);
         if (/^agi_(\w+)\:\s+(.*)$/) {
         $input{$1} = $2;
     }
}

my $dbh = DBI->connect ("dbi:mysql:host=$dbhost:database=$dbname","$dbuser","$dbpass") or die "Can't connect to database: $DBI::errstr\n";
my $sth = $dbh->prepare( "SELECT cid FROM known_numbers WHERE source='$input{callerid}'" );
$sth->execute();
@row = $sth->fetchrow_array();
$cidname = @row[0];
print "SET CALLERID \"@row\"<$input{callerid}>";

###############
# Broadcast info to MythTV
my $command;
$command = "cidbcast --once --file=$mythxmlfile 6947 $input{callerid} \"$cidname\" line";
system("$command &> /dev/null");

################
# Send out to squeezeboxes
# Code ripped from Squeezebox CID plugin by Max Spicer
# http://www.thespicers.net/cid.html
#

my $socket = IO::Socket::INET->new (PeerAddr => $serverAddress,
                                    PeerPort => $serverPort,
                                    Proto    => 'tcp',
                                    Type     => SOCK_STREAM)
or die 'Couldn\'t connect to server';

# Get the number of players
my $playerCount = sendAndReceive('player count ?');
$debug && print "$playerCount players found\n";

# Display message on each player and adjust volume if necessary
for (my $i = 0; $i < $playerCount; $i++) { my $playerId = sendAndReceive("player id $i ?"); # Put the players display at max brightness if it's currently 0 my $powerState = sendAndReceive("$playerId power ?"); my $brightnessPref = $powerState ? 'powerOnBrightness' : 'powerOffBrightness'; my $brightness = sendAndReceive("$playerId playerpref $brightnessPref ?"); $debug && print "brightness: $brightness\n"; if ($brightness == 0) { sendAndReceive("$playerId playerpref $brightnessPref 4"); } $cidname =~ s/\s/%20/g; $debug && print("Sending: $playerId display Incoming%20call:%20$input{callerid} $cidname $displayTime\n"); sendAndReceive("$playerId display Incoming%20call:%20$input{callerid} $cidname $displayTime"); # Drop the volume if necessary my $playerMode = sendAndReceive("$playerId mode ?"); $debug && print "playerMode: $playerMode\n"; if ($playerMode eq "play" && sendAndReceive("$playerId mixer volume ?") > $maxVolume) {
    $debug && print "Decreasing volume\n";
    sendAndReceive("$playerId mixer volume $maxVolume");
  }
}
$debug && print "\n";
exit 1;

# Send given cmd to $socket and return answer with original command removed from
# front if present.  Routine nicked from code by Felix Mueller. :-)
sub sendAndReceive {
  my $cmd = shift;
  return if( $cmd eq "");

  print $socket "$cmd\n";
  $debug > 1 && print "Sent $cmd to server\n";
  my $answer = <$socket>;
  $debug > 1 && print "Server replied: $answer\n";
  $answer =~ s/$cmd //i;
  $answer =~ s/\n//;

  return $answer;
}

Database table structure

mysql> describe known_numbers;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| source | varchar(13) |      | PRI |         |       |
| cid    | varchar(26) |      |     |         |       |
+--------+-------------+------+-----+---------+-------+