Prototyyppikoodi alla, kömpelö mutta tuntuu toimivan. Tuo on cronilla ajossa tasatunnein. Tällä hetkellä se ottaa kuluvan vuorokauden ja hakee sieltä ne 14 lämmitystuntia, ts aamuyöllä se katsoo lähes 24h eteenpäin ja myöhään illalla 0 tuntia. Periaatteessa se voisi myös käyttää liukuvaa aikaikkunaa, mutta logiikka pitäisi miettiä uusiksi.
Tuntien määrä ulkolämpötilan mukaan on aika suoraviivaista hakea, katsoo vaan käppyröistä millä ulkolämpötilalla sisälämpö ei enää pysy tarpeeksi korkealla. Tosin sen säätäminen kestää kauan, kun siellä on tuulen, asumisen, takan ja kevätauringon aiheuttama kohina seassa.
Toinen raspi säätää jakotukkien sulkuja (talossa lähemmäs 30 piiriä) huonekohtaisten anturien (18s20 muistaakseni) avulla. Tukeille menee 8-kanavaisia OneWire-kytkimiä joissa darlington arrayt 24V toimilaitteita ajamassa. Toiminut moitteetta kohta 9 vuotta. Siihen kun jaksaisi lisätä ulkolämpötilan, talon sähkömittarin impulssilaskimen ja lämpöpumpun sähkönkulutuksen niin olisi aika päheä. Miksei sitten samaan syssyyn myös tuulimittari ja auringonpaiste.
#!/usr/bin/python3
from datetime import datetime, timezone
# Import library for fetching Elspot data
from nordpool import elspot, elbas
from pprint import pprint
from datetime import datetime, timezone
import pifacedigitalio
def unit(price):
# € per MWh -> € per kWh
return price/1000
pf = pifacedigitalio.PiFaceDigital(init_board=True)
# Initialize class for fetching Elspot prices
prices_spot = elspot.Prices()
# Fetch hourly Elspot prices for Finland and print the resulting dictionary
pr = prices_spot.hourly(areas=['FI'], end_date= datetime.today())["areas"]["FI"]["values"]
# sort by cheapest first
sorted_p = sorted(pr, key=lambda kv: kv["value"])
prices = sorted(list(map(lambda x: x["value"], pr)))
avg = sum(prices)/len(prices)
print("-----")
print("It's", datetime.today())
print("Average price: %.3f" % unit(avg))
# price limit for not caring
min_price = 0.02 # € / kWh
# max oper hours per day
# pick price which covers at least this many hours a day
max_hours = 14
limit_price = unit(prices[max_hours-1])
#limit_price = unit(avg)
print("Limit price: %.3f" % limit_price)
resolved = False
on = False
now = datetime.now(timezone.utc).astimezone()
used_val = 0
allowed_prices = []
for i in range(0, len(sorted_p)):
p = sorted_p[i]
s = p["start"].astimezone()
e = p["end"].astimezone()
val = unit(p["value"]) # € per kWh
print("%d: %s - %s: %.3f %s %.3f" % (i, s, e, val, (val <= limit_price), min_price))
p["allow"] = (val <= limit_price)
if p["allow"]:
allowed_prices.append(val)
if now >= s and now < e:
if val < min_price:
print("Don't care of pricing, allow")
pf.relays[1].turn_off()
resolved = True
on = True
elif val <= limit_price:
print("Within acceptable price range, allow")
pf.relays[1].turn_off()
resolved = True
on = True
else:
print("Not in acceptable price range, prevent")
pf.relays[1].turn_on()
#pio.digital_write(1, 1)
resolved = True
on = False
used_val = val
if not resolved:
print("----Not resolved, allow just in case")
pf.relays[1].turn_off()
res = "ON" if on else "OFF"
if not resolved:
res = "??? (ON)"
allowed_avg = sum(allowed_prices) / len(allowed_prices)
i = ''
for p in pr:
i += '.' if p["allow"] else 'X'
print(i)
print("Overview: %s, avg %.3f, allowed avg %.3f, price %.3f, limit %.3f, result %s" % (now, unit(avg), allowed_avg, used_val, limit_price, res))