|
- import arrow
- import random
- import pprint
- import json
-
- from datetime import datetime, timedelta
-
- rand = random.Random('a seed')
-
- tz = 'US/Pacific'
-
- startdate = arrow.Arrow(2019, 11, 1, tzinfo=tz)
- enddate = arrow.Arrow(2019, 12, 10, tzinfo=tz)
-
- meanwhprod = 20000
- sigwhprod = 2000
-
- def drange(s, e, interval):
- cmpfun = lambda s, e, ts, te: te < e
- if e < s:
- interval = -interval
- cmpfun = lambda s, e, ts, te: te > e
- ts = s.clone()
- te = ts + interval
- #print('dr:', repr((s, e, ts, te, cmpfun(s, e, ts, te), interval)))
- while cmpfun(s, e, ts, te):
- yield ts + (te - ts)
- ts, te = te, te + interval
-
- # idea:
- # first hour linear ramp up (25% in first half, 75% in second half)
- # middle 5 hours near constant generation
- # first/tailing linear is equiv of an hour total, so total power / 6
-
- # approx 7 hours time
- def makestartend(t):
- s = t.replace(hour=9).shift(minutes=rand.gauss(30, 10))
- e = t.replace(hour=16).shift(minutes=rand.gauss(30, 10))
-
- return (s, e)
-
- def normdist(small, big, amount, minsize):
- '''Distribute most twoards the big side, total distribute amount
- over the entire range, [small, big].
- '''
-
- ret = []
-
- timediff = abs(big - small)
- if timediff < minsize:
- scaledamount = amount * (timedelta(hours=1) / timediff)
- midpnt = small + (big - small) / 2
- #print('ndf:', repr((small, big, midpnt, amount, scaledamount)))
- return [ (midpnt, scaledamount) ]
-
- #print('nd:', repr((small, big, amount)))
- dist = big - small
- halfpoint = small + (dist / 9 * 5)
- ret.extend(normdist(small, halfpoint, amount / 2, minsize))
- ret.extend(normdist(halfpoint, big, amount / 2, minsize))
-
- #print('ndr:')
- #pprint.pprint(ret)
- return ret
-
- def linramp(start, end, wtarget, minsize):
- mid = start + (end - start) / 2
- timediff = abs(end - start)
- ret = []
-
- ndates = abs((end - start) / minsize)
- #print('lr', ndates)
- for x, i in enumerate(drange(start, end, minsize)):
- #print(repr((x, i)))
- yield (i, x / ndates * wtarget)
-
- def makeconsumption(s, mean, sig, interval):
- s = s.replace(hour=0, minute=0, second=0)
- e = (s + timedelta(days=1)) - interval
-
- ret = [ (i, rand.gauss(mean, sig)) for i in drange(s, e, interval) ]
-
- return ret
-
- def distribute(s, e, prod, minsize):
- onehour = timedelta(hours=1)
- totaltime = e - s
- mid = s + totaltime / 2
- startrampend = s + onehour
- endrampstart = e - onehour
-
- # prod == wh
- wtarget = prod / ((totaltime + onehour).seconds / 60 / 60)
-
- ret = []
-
- #print('d:', repr((s, e)))
- ret.extend(linramp(s, startrampend, wtarget, minsize))
-
- for i in drange(startrampend, endrampstart, minsize):
- ret.append((i, wtarget))
-
- ret.extend(linramp(e, endrampstart, wtarget, minsize))
-
- ret.sort()
- #pprint.pprint(ret)
-
- return ret
-
- #print('start')
-
- prodpoints = []
- prodindex = []
- conspoints = []
- consindex = []
-
- def serializearrowasmili(obj):
- if not isinstance(obj, arrow.Arrow):
- raise TypeError
-
- return int(obj.float_timestamp*1000)
-
- for i in arrow.Arrow.range('day', startdate, enddate):
- whprod = rand.gauss(meanwhprod, sigwhprod)
- s, e = makestartend(i)
- noon = i.replace(hour=12)
-
- prodindex.append((noon, whprod))
- #print(repr(i), whprod)
-
- dist = []
-
- tmppoints = makeconsumption(s, rand.uniform(400,800), 100, timedelta(minutes=1))
- consindex.append((noon, sum((i[1] / 60 for i in tmppoints), 0)))
- conspoints.extend(tmppoints)
-
- # zero points for non-production
- import sys
- dist.extend(distribute(i, s, 0, timedelta(minutes=5)))
-
- # production
- dist.extend(distribute(s, e, whprod, timedelta(seconds=20)))
-
- # zero points for non-production
- eod = i.replace(hour=23, minute=55)
- dist.extend(distribute(e, eod, 0, timedelta(minutes=5)))
-
- # print timestamps as miliseconds
- if False:
- dist = ((int(a.float_timestamp*1000), b) for a, b in dist)
-
- # print space delimited time, else json
- if False:
- print('\n'.join('%s %s' % (a, b) for a, b in dist))
- else:
- #print(json.dumps(tuple(dist), indent=2))
- prodpoints.extend(dist)
-
- for i in { 'prodpoints', 'prodindex', 'conspoints', 'consindex',}:
- v = locals()[i]
- v = [ (x, int(y)) for x, y in v ]
- locals()[i] = v
-
- #conspoints = [ (x, -y) for x, y in conspoints ]
-
- print('fakedata =', json.dumps(dict(production=prodpoints, prodindex=prodindex, consumption=conspoints, consindex=consindex), default=serializearrowasmili, indent=1))
|