Friday, 23 December 2016

Home Heating IoT Project - Software planning

For this project I want to be able to control the room heating in my house either manually or on a timed system.

I decided to plan it using a flowchart, as I couldn't get my head around the programming easily without visualising it.

Here's the first draft and I'm pleased how it turned out:
This image was made at lucidchart.com - so easy to use!


The earlier posts in this project can be found here: http://raspitech.blogspot.com/2016_10_01_archive.html

Electracker - More energy consumption analysis

Now that I have a few weeks of data, I wanted to get daily graphs to look for patterns. I amended the original code to create them:

Not as useful as I'd hoped, but the average consumption per day is definitely interesting.

The coding is pretty terrible, sorry. If I was starting from scratch I'd use datetime module functions to do the date work and include some error handling to stop the program crashing when data is missing for an hour. Because I was pushed for time and had a working program already in place  to modify, it was the quickest solution.

Code, such as it is,  is here:
https://github.com/jcwyatt/electracker/blob/master/elecanalDailyGraphs.py





#program to analyse electricity use over time by hour.

#open a file

#for each hour:
#read it line by line
#bucket into hour
#get total
#get average for each hour

#enhancements to follow: daily charts, date range charts, movie!

import csv
import os
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt



startDay = 20
startMonth = 12

while True:
 elecByHour=[]
 dailyTotal=0
 dailyReadings=0

 for i in range (0,24):     #for each hour
    with open ('feeds.csv', 'rb') as csvfile:
     rawelecdata = csv.DictReader(csvfile)
     
     j=0
     hourelectot=0

     for row in rawelecdata:
      if int(row['created_at'][11:13])==i and int(row['created_at'][8:10])==startDay and int(row['created_at'][5:7])==startMonth:
       hourelectot += float(row['field1'])
       j +=1
     
    print(i,hourelectot/j,j) #useful to for debugging

    elecByHour.append(hourelectot/j) #add average for the current hour to list

    #calculate average for day:
    dailyTotal = dailyTotal + hourelectot
    dailyReadings = dailyReadings + j


 dailyAverage = dailyTotal/dailyReadings
#plot the graph:

 y = (elecByHour)
 N = len(y)
 x = range(N)
 width = 1/1.5
 plt.xlabel ('Time of Day / hr')
 plt.ylabel ('kW')
 plt.ylim((0,6))
 plt.title('Consumption for '+ str(startDay) + '/' + str(startMonth) + ' Average = ' + str(dailyAverage)+'kW')
 plt.bar(x, y, width, color="blue")
 plt.savefig('elecByHour' + str(startMonth) + str(startDay) + '.png')
 plt.close()
 
 #os.system('xviewer elecByHour.png &')
 startDay += 1


Tuesday, 29 November 2016

Pi Light and Movie Quote Alarm Clock

Sorry, No documentation on this one. Rough and ready test program.

Turns a blue LED on in the morning (and evening..don't ask) to wake me up, but also plays a random selection from a bank of quotes.  

from gpiozero import LED
from time import sleep
import datetime
import os
import random

led = LED(4)

overRide='auto'
amOn=datetime.time(05,50,00)
amOff=datetime.time(06,30,00)
pmOn=datetime.time(21,30,00)
pmOff=datetime.time(22,45,00)

print (pmOff)
soundTrigger=0
while True:
        while overRide=='auto':

                timeNow=datetime.datetime.now().time()
                soundchoice = str(random.randint(1,5))
                playsound=('aplay '+soundchoice+'.wav')
                if timeNow>pmOn and timeNow<pmOff or timeNow>amOn and timeNow<amOff:
                        led.on()
                        print('led on')
                        soundTrigger+=1
                        if soundTrigger==1:
                                os.system(playsound)
                else:
                        led.off()
                        print('led off')
                        soundTrigger=0
                sleep(60)

Live Energy Consumption in a 'Google Guage'


The author can't find a way to make this visualisation public. Wierd user interface at Thingspeak.

Monday, 28 November 2016

Electracker - Analysis of 2 weeks of data

Earlier this month I got serious about logging my home electrical energy consumption.

The Pi tasked with this job has run continuously for two weeks, happily logging data:

https://thingspeak.com/channels/182833

And is still doing so.

I wanted to analyse this data to get an average picture of the daily consumption, by hour:


A typical weekday looks like this:

The code is here:

https://raw.githubusercontent.com/jcwyatt/electracker/master/elecanal.py


The only thing I'd do to update this is to plonk the overall average consumption for the time period shown as a data box on the graph, e.g. "Average = 0.871 kW" for the main graph.

Wednesday, 16 November 2016

Circles in Minecraft - Minecraft Pi and Python

Circles in Minecraft?

Using Minecraft Pi, you can write code to place blocks. This means, in theory, you can code objects you could never build accurately - like giant circles.

I had a go at some maths around this in a spreadsheet using the formula for a circle



where x and y are coordinates.

It came out like this:



Which is circular if nothing else.

I don't like the gaps near the axes but with some clever programming (which I'll have to google!) I reckon eventually I could get rid of them.


Trig Method


I realised the numbers above follow 2 overlapping sine waves, so a quick search revealed this:

"A circle can be defined as the locus of all points that satisfy the equations
x = r cos(t)    y = r sin(t)
where x,y are the coordinates of any point on the circle, r is the radius of the circle and 
t is the parameter - the angle subtended by the point at the circle's center."
from  http://www.mathopenref.com/coordparamcircle.html (there's an interactive applet)



So  by carefully choosing the angular interval 't' you should be able to put blocks precisely where you want them in the circle.

Here's my first go in the spreadsheet:


You can see there are still gaps and the numbers in the columns are all over the place. Think the trig functions are working in radians but I entered angles in degrees. 

Using radians instead of degrees:


To plot more points, I'd have to reduce the interval in column 1 to give more points between 0 and 2.

Imagine that in Minecraft! 

I've a Pi 3 that I've just set up to run headless, so I'll move onto that next.....

The Results!


nested loop of expanding rising circles. Feels like an amphitheatre inside.

Simple cylinder - circles on top of circles
This one was weird - a cylinder with different block types in each layer. Unfortunately 2 of them were lava and water.
One massive circle. 

 The code for these:



from mcpi.minecraft import Minecraft
import math

mc = Minecraft.create()
#get players position
x,y,z=mc.player.getPos()

#move out of the way, there's something coming
mc.player.setPos (x,y+50,z)


r=15 #radius factor

for q in range (1,4):  #nested loop for when you want multiple circles
    for i in range(0,r*6):  #sets how many blocks comprise the shape
        j = float(i)/(r*3)  #gives max j of 2 (to give  2*pi radians for trig))

        blockXPos = r*math.cos(j*math.pi)  #sets x coordinate of block
        blockZPos = r*math.sin(j*math.pi)  #sets z coordinate of block

        mc.setBlock(blockXPos+x,y+q,blockZPos+z,1) #places a block in the circle



You could use code like this to plot other mathematical functions. Even 3D ones:

Quadric_Hyper_One
Its something called a quadric surface:



Something about that makes me feel like I've earned a glass of wine!




Tuesday, 15 November 2016

Electracker - Domestic Energy Consumption Logger

I've written about this project before but I revived it after a visit to Jersey Tech Fair and meeting the nice chaps at Jersey Electricity. They tried to sell me 'Nest', a home heating automation system (they may have succeeded. Watch this space.) But we also discussed electricity consumption.

I've had a Pi attached to my electricity meter for over a year now, but doing nothing.
Now rekindled, it seems to be happily tracking my energy usage and logging the results at Thingspeak.

I'm going to leave it for a bit and then plan to do a frequency analysis on a few days worth of data.

https://thingspeak.com/channels/182833





I also added this widget to my phone:

https://play.google.com/store/apps/details?id=ua.livi.thingspeakmonitor&hl=en

So now I can see live updates of my energy consumption as long as I have wifi/3G:








The code is here at github:

https://github.com/jcwyatt/electracker/blob/master/electracker_bars.py







Things I've learnt:

1) The wifi connection was really flaky - an Edimax attached to a Pi Zero. I've replaced the Edimax with a bulky Netgear with an ariel but this seems quite erratic too. Tried a better power supply.  Seems slightly better now. Made it a real pain to SSH into the Pi and also writing to Thingspeak.

2) You can't have it all ways (yet). I was initially recording every interval between flashes, and getting a really accurate reading, but couldn't write this to Thingspeak as it took too long and caused missed readings and errors due to the delay.
Now I'm counting the number of flashes in a 2 minute period and writing a calculated consumption based on this to Thingspeak. Advantages are that it give a consistent rate of readings, which looks great on Thingspeak, and at high consumption rates it should be very accurate, albeit for an average consumption over 2 minutes. However at low consumption rates the accuracy drops off; the small number of flashes per 2 minute interval kills the resolution on the measurements.

Solution:


Some kind of hybrid where it records the interval between flashes and averages this out over 2 minutes, and then writes this average data to TS.
Should be possible:

<pseudocode>
while True:
     Reset total time to 0
     Reset flashes to 0
     Wait for a flash
     Start the timer
     For 2 minutes:
            Wait for a flash
            stop the timer
            record the flash interval
            start the timer
            flashes +=1
            total time = total time + flash interval
            wait 0.07s to check the LED is off again
            repeat
      average = totaltime/flashes
      Consumption = 1.125/average
      Write Consumption to Thingspeak
</pseudocode>