Browse Source

add support for fetching grid data...

main
John-Mark Gurney 4 years ago
parent
commit
956c7feab9
2 changed files with 73 additions and 4 deletions
  1. +1
    -0
      setup.py
  2. +72
    -4
      solardash/__init__.py

+ 1
- 0
setup.py View File

@@ -16,6 +16,7 @@ setup(name='solardash',
install_requires=[ install_requires=[
'aiohttp', 'aiohttp',
'RainEagle @ git+https://www.funkthat.com/gitea/jmg/RainEagle.git', 'RainEagle @ git+https://www.funkthat.com/gitea/jmg/RainEagle.git',
'mock',
], ],
extras_require = { extras_require = {
'dev': [ 'coverage' ], 'dev': [ 'coverage' ],


+ 72
- 4
solardash/__init__.py View File

@@ -27,16 +27,19 @@ import aiohttp
import asyncio import asyncio
import concurrent import concurrent
import logging import logging
import json
import mock
import os import os
import shutil import shutil
import solardash
import tempfile import tempfile
import unittest import unittest
import urllib import urllib


logging.basicConfig(level=logging.DEBUG)
#logging.basicConfig(level=logging.DEBUG)


from aiohttp import web from aiohttp import web
from RainEagle.parse import LogDir as RELogDir, _cmaiter
from RainEagle.parse import LogDir as RELogDir, _cmaiter, MeterRead


# https://twitter.com/encthenet/status/1220412987732787200?s=20 # https://twitter.com/encthenet/status/1220412987732787200?s=20
aiter = lambda x: x.__aiter__() aiter = lambda x: x.__aiter__()
@@ -106,10 +109,21 @@ class SolarDataWS(object):


injecttask = asyncio.create_task(injector()) injecttask = asyncio.create_task(injector())


#pending = []
async for msg in ws: async for msg in ws:
if msg.type == aiohttp.WSMsgType.TEXT and msg.data == 'q': if msg.type == aiohttp.WSMsgType.TEXT and msg.data == 'q':
break
else:
break
elif msg.type == aiohttp.WSMsgType.TEXT:
fun, data = msg.data.split(' ', 1)
try:
fun = getattr(self, 'wst_%s' % fun)
# XXX add tests to make this a task
#pending.append(asyncio.create_task(fun(ws, data)))
await fun(ws, data)
except Exception: # pragma: no cover
import traceback; traceback.print_exc()
print('failed to handle msg:', repr(msg))
else: # pragma: no cover
print('unknown msg:', repr(msg)) print('unknown msg:', repr(msg))


injecttask.cancel() injecttask.cancel()
@@ -118,6 +132,14 @@ class SolarDataWS(object):


return ws return ws


async def wst_win(self, ws, data):
start, stop = (int(x) / 1000 for x in data.split())

griddata = [ (x.meterts, x.load * 1000) for x in self._raineagle[start:stop] ]

obj = dict(production=[], grid=griddata, consumption=[])
await ws.send_str('windata %s' % json.dumps(obj))

def get_routes(self): def get_routes(self):
return [ return [
web.get('/solar.ws', self.websocket_handler), web.get('/solar.ws', self.websocket_handler),
@@ -341,3 +363,49 @@ class Test(unittest.TestCase):
self.assertEqual(r[1].data, 'ng 1.0000') self.assertEqual(r[1].data, 'ng 1.0000')
finally: finally:
await runner.cleanup() await runner.cleanup()

@async_test
@mock.patch('solardash.RELogDir.__getitem__')
async def test_winowdata(self, relogdir):
loop = asyncio.get_event_loop()

runner = web.AppRunner(self._app)
await runner.setup()
try:
site = web.TCPSite(runner, 'localhost', self._webport)
await site.start()

# Test the websocket
r = []

async with aiohttp.ClientSession() as session, \
session.ws_connect(self.makeurl('solar.ws')) as ws:
startts = 128743
endts = 1987343

meterdata = [ MeterRead(x * 2, x * 2 + 1, 'bogus',
x, 12, 'kW', x * 5, -x * 5,
'kW') for x in (1, 2, 3, 4) ]
data = [ [x.meterts, x.load * 1000] for x in meterdata ]
relogdir.return_value = meterdata
windataresp = 'this is some response'

# send the window command
await ws.send_str('win %s %s' % (startts,
endts))

async for msg in ws:
r.append(msg)
if len(r) == 1:
break

# we get passed in miliseconds from JS, but
# we want seconds
relogdir.assert_called_with(slice(startts /
1000, endts / 1000))
self.assertEqual(r[0].type, aiohttp.WSMsgType.TEXT)
obj = json.loads(r[0].data.split(' ', 1)[1])
self.assertEqual(obj, dict(production=[],
grid=data, consumption=[]))
finally:
await runner.cleanup()

Loading…
Cancel
Save