====== LEDpi - Visualisierung per LED ======
Visualisierung des Stromverbrauchs / PV Einspeisung per farbiger LEDs
===== Hardware =====
* raspberry PI
* WS2801 LEDs (http://www.ebay.de/sch/?_nkw=WS2801%20RGB%20LED) entweder als Strip oder einzeln
* stärkeres 5V Netzteil (je nach Anzahl der LEDs 20-40 Watt)
* ein wenig Holz, Farbe und ein Alu Profil für die LEDs (https://www.google.de/search?q=led+streifen+alu+profil)
=== Verkabelung / Aufbau ===
{{https://learn.adafruit.com/system/assets/assets/000/001/589/medium800/raspberry_pi_diagram.png}}
{{:software:frontends:141012-imag1335.jpg?direct&200|}}
{{:software:frontends:141012-imag1338.jpg?direct&200|}}
{{:software:frontends:141012-imag1337.jpg?direct&200|}}
===== Software =====
=== Prereqs ===
Damit die LEDs per serieller Schnittstelle angesteuert werden können, muss die Schnittstelle aktiviert werden.
Dazu installiert man (sofern noch nicht geschehen) die python-dev und git Tools mit
apt-get install git python-dev
Dann holt man sich py-spidev und installiert es:
git clone git://github.com/doceme/py-spidev
cd py-spidev
sudo python setup.py install
=== Das eigentliche Script ===
Das PixelPi Script von https://github.com/scottjgibson/PixelPi wurde verschlankt und etwas umgebaut. So ist dieses Python Scripte entstanden.
Das Scrpit übernimmt folgende Funktionen:
* Auslesen der aktuellen Werte aus der Volkszaehler Middleware
* Anzeigen der Leistung der einzelnen Kanäle in verschiedenen Farben (z.B. PV Leistung in Blau, davon eingespeister Strom in Grün, Verbrauch in Rot) Pro 500Watt wird eine LED voll erleuchtet (SCALE), die letzte dann in entsprechener Helligkeit
* die oberste LED blinkt grün um zu zeigen das das Script noch lebt
import httplib2 as http
import json
from pprint import pprint
import argparse
import csv
import socket
import time
try:
from urlparse import urlparse
except ImportError:
from urllib.parse import urlparse
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json; charset=UTF-8'
}
targetELW = urlparse('http://sqlserver/middleware.php/data/f2059450-bbbe-11e3-aabc-7bfab5f4b02e.json?from=now')
targetHeizung = urlparse('http://sqlserver/middleware.php/data/26bce7c0-bbc2-11e3-b634-3334d2c934ae.json?from=now')
targetHaus = urlparse('http://sqlserver/middleware.php/data/32e8d3d0-bbc2-11e3-8f42-eb76d7115f4b.json?from=now')
targetPV = urlparse('http://sqlserver/middleware.php/data/4186f3e0-bbc2-11e3-a87a-8b10388c97ce.json?from=now')
gamma = bytearray(256)
spi_dev_name = '/dev/spidev0.0'
PIXEL_SIZE = 3
SCALE = 500
BLACK = bytearray(b'\x00\x00\x00')
BLUE = bytearray(b'\x00\x00\xff')
CYAN = bytearray(b'\x00\xff\xff')
FUCHSIA = bytearray(b'\xff\x00\xff')
GREEN = bytearray(b'\x00\xff\x00')
RED = bytearray(b'\xff\x00\x00')
WHITE = bytearray(b'\xff\xff\xff')
YELLOW = bytearray(b'\xff\xff\x00')
# Apply Gamma Correction and RGB / GRB reordering
# Optionally perform brightness adjustment
def filter_pixel(input_pixel, brightness):
output_pixel = bytearray(PIXEL_SIZE)
input_pixel[0] = int(brightness * input_pixel[0])
input_pixel[1] = int(brightness * input_pixel[1])
input_pixel[2] = int(brightness * input_pixel[2])
output_pixel[0] = gamma[input_pixel[0]]
output_pixel[1] = gamma[input_pixel[1]]
output_pixel[2] = gamma[input_pixel[2]]
return output_pixel
def write_stream(pixels):
spidev.write(pixels)
return
# MAIN
spidev = file(spi_dev_name, "wb")
for i in range(256):
gamma[i] = int(pow(float(i) / 255.0, 2.5) * 255.0)
Blinker = 0
pixel_output = bytearray(16 * PIXEL_SIZE + 3)
method = 'GET'
body = ''
h = http.Http()
while True:
responseELW, contentELW = h.request(targetELW.geturl(),method,body,headers)
ELW = json.loads(contentELW)
ELWled = int(float(ELW["data"]["tuples"][0][1])) / SCALE
responseHeizung, contentHeizung = h.request(targetHeizung.geturl(),method,body,headers)
Heizung = json.loads(contentHeizung)
Heizungled = int(float(Heizung["data"]["tuples"][0][1])) / SCALE
responseHaus, contentHaus = h.request(targetHaus.geturl(),method,body,headers)
Haus = json.loads(contentHaus)
Haus["data"]["tuples"][0][1] = Haus["data"]["tuples"][0][1] - ELW["data"]["tuples"][0][1]
Hausled = int(float(Haus["data"]["tuples"][0][1])) / SCALE
responsePV, contentPV = h.request(targetPV.geturl(),method,body,headers)
PV = json.loads(contentPV)
PVled = int(float(PV["data"]["tuples"][0][1])) / SCALE
led = 0
print "Haus: ", int(float(Haus["data"]["tuples"][0][1])), " Hausled: ",Hausled, "PV: ", int(float(PV["data"]["tuples"][0][1])) , " PVled ",PVled
for led in range(19):
pixel_output[led * PIXEL_SIZE:] = filter_pixel(BLACK, 1)
if Hausled > led:
pixel_output[(led * PIXEL_SIZE)+0] = '\xff'
elif (Hausled == led) and (int(float(Haus["data"]["tuples"][0][1])) > 440):
pixel_output[(led * PIXEL_SIZE)+0] = int(( float(Haus["data"]["tuples"][0][1]) % SCALE) / SCALE * 255)
if -Hausled > led:
pixel_output[(led * PIXEL_SIZE)+1] = '\xff'
elif (-Hausled == led) and ( int(float(Haus["data"]["tuples"][0][1])) < -440):
pixel_output[(led * PIXEL_SIZE)+1] = int(( float(Haus["data"]["tuples"][0][1]) % SCALE) / SCALE * 255)
if (PVled > led) and (PVled > -Hausled) and (PVled > Hausled):
pixel_output[(led * PIXEL_SIZE)+2] = '\xff'
elif PVled == led:
pixel_output[(led * PIXEL_SIZE)+2] = int(( float(PV["data"]["tuples"][0][1]) % SCALE) / SCALE * 255)
if (led == 18):
if (Blinker == 0):
Blinker = 1
pixel_output[led * PIXEL_SIZE:] = filter_pixel( bytearray(b'\x00\x1C\x00'), 1)
else:
Blinker = 0
pixel_output[led * PIXEL_SIZE:] = filter_pixel(BLACK, 1)
for c in pixel_output: print(c),
print('\n')
write_stream(pixel_output)
spidev.flush()
time.sleep(2)