Compare commits

..

3 Commits

Author SHA1 Message Date
278d30c421 Store strong references to async tasks
Reason: https://news.t0.vc/IEUC
2023-02-12 18:38:36 +00:00
f01eeacbce Use UTC time instead of timestamp 2023-01-12 18:32:20 +00:00
af87378fd3 idk 2022-01-10 07:57:41 +00:00
3 changed files with 90 additions and 87 deletions

View File

@@ -47,3 +47,8 @@ p {
margin: 0.25em; margin: 0.25em;
} }
.recharts-wrapper p {
color: initial;
font-size: initial;
}

View File

@@ -6,11 +6,12 @@ import './App.css';
function App() { function App() {
const [data, setData] = useState(false); const [data, setData] = useState(false);
const [history, setHistory] = useState(false);
useEffect(() => { useEffect(() => {
const get = async() => { const get = async() => {
try { try {
const res = await axios.get('https://reg.t0.vc/solar.json'); const res = await axios.get('https://solar-api.dns.t0.vc/data');
setData(res.data); setData(res.data);
} catch (error) { } catch (error) {
setData(false); setData(false);
@@ -18,97 +19,94 @@ function App() {
}; };
get(); get();
const interval = setInterval(get, 1000); const interval = setInterval(get, 30000);
return () => clearInterval(interval); return () => clearInterval(interval);
}, []); }, []);
const listen = () => { useEffect(() => {
var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); const get = async() => {
var myArrayBuffer = audioCtx.createBuffer(2, audioCtx.sampleRate * 5, audioCtx.sampleRate); try {
for (var channel = 0; channel < myArrayBuffer.numberOfChannels; channel++) { const date = moment().format('YYYY-MM-DD');
var nowBuffering = myArrayBuffer.getChannelData(channel); const res = await axios.get('https://solar-api.dns.t0.vc/history/'+date);
for (var i = 0; i < myArrayBuffer.length; i++) { setHistory(res.data);
nowBuffering[i] = data.history[i % data.history.length].total / 24000.0; } catch (error) {
setHistory(false);
} }
} };
var source = audioCtx.createBufferSource();
source.buffer = myArrayBuffer; get();
source.connect(audioCtx.destination); const interval = setInterval(get, 30000);
source.start(); return () => clearInterval(interval);
} }, []);
return ( return (
<div> <div>
{history ?
<ResponsiveContainer width='100%' height={300}>
<LineChart data={history}>
<XAxis
dataKey='time'
minTickGap={10}
tickFormatter={timeStr => moment(timeStr).format('HH:mm')}
/>
<YAxis
domain={[0, 6000]}
/>
<CartesianGrid strokeDasharray='3 3'/>
<Tooltip
labelFormatter={timeStr => 'Time: ' + moment(timeStr).format('HH:mm')}
/>
<Line
type='monotone'
dataKey='actual_total'
name='Watts'
stroke='#ff5900'
strokeWidth={2}
dot={false}
animationDuration={1000}
/>
</LineChart>
</ResponsiveContainer>
:
<p>Loading...</p>
}
{data ? {data ?
<div> <div className='container'>
<ResponsiveContainer width='100%' height={300}> <p>Total: {data.actual_total} W {parseInt(data.actual_total / 5985 * 100)}%</p>
<LineChart data={data.history}>
<XAxis
dataKey='time'
minTickGap={10}
tickFormatter={timeStr => moment.utc(timeStr).format('HH:mm')}
/>
<YAxis />
<CartesianGrid strokeDasharray='3 3'/>
<Tooltip
labelFormatter={timeStr => 'Time: ' + moment.utc(timeStr).format('HH:mm')}
/>
<Line <p>Today: {data.today_energy} kWh</p>
type='monotone'
dataKey='total'
name='Watts'
stroke='#ff5900'
strokeWidth={2}
dot={false}
animationDuration={1000}
/>
</LineChart>
</ResponsiveContainer>
<button onClick={listen}>Listen</button> <p>Updated: {data.timestamp.split(' ')[1]}</p>
{data.night ? <p>Individual panels:</p>
<div className='container'>
<p>The sun has set 😴</p>
</div>
:
<div className='container'>
<p>Total: {data.actual_total} W {parseInt(data.actual_total / 5985 * 100)}%</p>
<p>Today: {data.today_energy} kWh</p> <div className='panels'>
{Object.values(data.inverters).map((x, i) =>
<>
<div
className='panel'
style={{ backgroundColor: `hsl(21, 100%, ${x.power[0]/315*50}%)` }}
>
<div className='panel-label'>
{x.power[0]}
</div>
</div>
<p>Updated: {data.timestamp.split(' ')[1]}</p> {i != 2 &&
<div
<p>Individual panels:</p> className='panel'
style={{ backgroundColor: `hsl(21, 100%, ${x.power[1]/315*50}%)` }}
<div className='panels'> >
{Object.values(data.inverters).map((x, i) => <div className='panel-label'>
<> {x.power[1]}
<div
className='panel'
style={{ backgroundColor: `hsl(21, 100%, ${x.power[0]/315*50}%)` }}
>
<div className='panel-label'>
{x.power[0]}
</div>
</div> </div>
</div>
{i != 2 && }
<div </>
className='panel' )}
style={{ backgroundColor: `hsl(21, 100%, ${x.power[1]/315*50}%)` }} </div>
>
<div className='panel-label'>
{x.power[1]}
</div>
</div>
}
</>
)}
</div>
</div>
}
</div> </div>
: :
<p>Loading...</p> <p>Loading...</p>

View File

@@ -7,13 +7,13 @@ logging.getLogger('aiohttp').setLevel(logging.DEBUG if os.environ.get('DEBUG') e
import asyncio import asyncio
from aiohttp import web from aiohttp import web
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
import pytz import pytz
from APSystemsECUR import APSystemsECUR from APSystemsECUR import APSystemsECUR
ECU_IP = '192.168.69.153' ECU_IP = '192.168.69.153'
LISTEN_IP = '192.168.69.100' LISTEN_IP = '192.168.69.106'
ecu = APSystemsECUR(ECU_IP) ecu = APSystemsECUR(ECU_IP)
app = web.Application() app = web.Application()
prev_ecu_timestamp = None prev_ecu_timestamp = None
@@ -60,7 +60,7 @@ async def get_data():
if data['timestamp'] != prev_ecu_timestamp: if data['timestamp'] != prev_ecu_timestamp:
total = 0 total = 0
timestamp = datetime.utcnow() utctime = datetime.now(timezone.utc)
for i in data['inverters'].values(): for i in data['inverters'].values():
total += i['power'][0] total += i['power'][0]
@@ -73,7 +73,7 @@ async def get_data():
points = [] points = []
for i in data['inverters'].values(): for i in data['inverters'].values():
points.append({ points.append({
'time': timestamp, 'time': utctime,
'measurement': 'inverter', 'measurement': 'inverter',
'tags': {'ecu': data['ecu_id'], 'inverter': i['uid']}, 'tags': {'ecu': data['ecu_id'], 'inverter': i['uid']},
'fields': { 'fields': {
@@ -85,7 +85,7 @@ async def get_data():
}) })
points.append({ points.append({
'time': timestamp, 'time': utctime,
'measurement': 'panel', 'measurement': 'panel',
'tags': {'ecu': data['ecu_id'], 'inverter': i['uid'], 'channel': '0'}, 'tags': {'ecu': data['ecu_id'], 'inverter': i['uid'], 'channel': '0'},
'fields': { 'fields': {
@@ -96,7 +96,7 @@ async def get_data():
}) })
points.append({ points.append({
'time': timestamp, 'time': utctime,
'measurement': 'panel', 'measurement': 'panel',
'tags': {'ecu': data['ecu_id'], 'inverter': i['uid'], 'channel': '1'}, 'tags': {'ecu': data['ecu_id'], 'inverter': i['uid'], 'channel': '1'},
'fields': { 'fields': {
@@ -107,7 +107,7 @@ async def get_data():
}) })
points.append({ points.append({
'time': timestamp, 'time': utctime,
'measurement': 'ecu', 'measurement': 'ecu',
'tags': {'ecu': data['ecu_id']}, 'tags': {'ecu': data['ecu_id']},
'fields': { 'fields': {
@@ -165,6 +165,6 @@ if __name__ == '__main__':
app.router.add_get('/history/{date}', history) app.router.add_get('/history/{date}', history)
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
loop.create_task(run_proxies()) a = loop.create_task(run_proxies())
loop.create_task(get_data()) b = loop.create_task(get_data())
web.run_app(app, port=6901) web.run_app(app, port=6901)