You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
2.6 KiB
118 lines
2.6 KiB
import React, { useState, useEffect } from 'react'; |
|
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'; |
|
import axios from 'axios'; |
|
import moment from 'moment'; |
|
import './App.css'; |
|
|
|
function App() { |
|
const [data, setData] = useState(false); |
|
const [history, setHistory] = useState(false); |
|
|
|
useEffect(() => { |
|
const get = async() => { |
|
try { |
|
const res = await axios.get('https://solar-api.dns.t0.vc/data'); |
|
setData(res.data); |
|
} catch (error) { |
|
setData(false); |
|
} |
|
}; |
|
|
|
get(); |
|
const interval = setInterval(get, 30000); |
|
return () => clearInterval(interval); |
|
}, []); |
|
|
|
useEffect(() => { |
|
const get = async() => { |
|
try { |
|
const date = moment().format('YYYY-MM-DD'); |
|
const res = await axios.get('https://solar-api.dns.t0.vc/history/'+date); |
|
setHistory(res.data); |
|
} catch (error) { |
|
setHistory(false); |
|
} |
|
}; |
|
|
|
get(); |
|
const interval = setInterval(get, 30000); |
|
return () => clearInterval(interval); |
|
}, []); |
|
|
|
return ( |
|
<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 ? |
|
<div className='container'> |
|
<p>Total: {data.actual_total} W — {parseInt(data.actual_total / 5985 * 100)}%</p> |
|
|
|
<p>Today: {data.today_energy} kWh</p> |
|
|
|
<p>Updated: {data.timestamp.split(' ')[1]}</p> |
|
|
|
<p>Individual panels:</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> |
|
|
|
{i != 2 && |
|
<div |
|
className='panel' |
|
style={{ backgroundColor: `hsl(21, 100%, ${x.power[1]/315*50}%)` }} |
|
> |
|
<div className='panel-label'> |
|
{x.power[1]} |
|
</div> |
|
</div> |
|
} |
|
</> |
|
)} |
|
</div> |
|
</div> |
|
: |
|
<p>Loading...</p> |
|
} |
|
</div> |
|
); |
|
} |
|
|
|
export default App;
|
|
|