This subflow uses the http request node to fetch solar forecasts for geographical positions, using the API from https://forecast.solar/. Please check their website and consider getting a paid account.
Do note that, on a free account, you are limited in the number of requests to do. Also note that the data only gets updated once every 15 minutes, so there is no reason to query more often. There is rate limiting built in the subflow not to perform requests more than once every 15 minutes.
It uses the parameters as described on: http://doc.forecast.solar/doku.php
:apikey
- personal API key for registered users:lat
- latitude of location, -90 (south) … 90 (north); Internal precission is 0.0001 or abt. 10 m:lon
- longitude of location, -180 (west) … 180 (east); Internal precission is 0.0001 or abt. 10 m:dec
- plane declination, 0 (horizontal) … 90 (vertical); Internal precission is integer:az
- plane azimuth, -180 … 180 (-180 = north, -90 = east, 0 = south, 90 = west, 180 = north); Internal precission is integer:kwp
- installed modules power in kilo watt peak (kWp)
You can choose between 3 different type of requests. Note that only estimate
is available on the free plan.
estimate
- this is the forecasted estimate that your panels should produce (given the right parameter settings)history
- historical data showing the long term averages for the days to come. See https://joint-research-centre.ec.europa.eu/pvgis-online-tool/pvgis-data-download/cm-saf-solar-radiation_en for where the data is fetched from.clear sky
- estimate given if there would be a clear sky tomorrow
In case of estimates, one of the following options can be selected:
watts
- Watts (power) average for the periodwatt_hours_period
- Watt hours (energy) for the periodwatt_hours
- Watt hours (energy) summarized over the daywatt_hours_day
- Watt hours (energy) summarized for each day
For the graph output there are some extra settings available:
- Output in kWh - when checked output can be set to kWh instead of Wh
- Show todays forecast - whether or not to include todays forecast
- Days to forecast - the number of days to forecast (excluding today). Note that you can not get more days forecasted than your API key allows.
- Widen graph - widen the graph to only show non-zero values
- Show day instead of date - Show the day instead of the date in the series
The optional horizon field can be filled out in case an object blocks your solar panels from the sun. See the description here on what numbers to fill out. Leave it empty if you have no objects blocking your panels.
It triggers when injecting a message into the node.
There are two outputs. The first output is an object with the result and a status message stored into the msg.payload
.
Most important is the msg.payload.result
, which contains the estimated production of the panels. E.g.:
payload: object
result: object
2022-11-28: 23
2022-11-29: 35
The msg.payload.message
gives information on how successful the query was, the exitcode of the query and the status of the rate limit (how many queries you have left).
The second output can be directly linked to a line or a bar chart, quickly giving a once-glance overview for the predicted forecast.
Initially the status of the note will be a blue dot, showing "Unknown limit", as it is unaware of the set ratelmits. After the first request, the returned ratelimit will be put in the text in the form of remaining/limit
. If more than half the limit is remaining, the dot will be green. If less then half the limit is remaining, the dot will be yellow. If no limit is left, the dot will turn red.
Please keep in mind that the ratelimit will be reset after one hour, so you can send a new request after that hour.
If you have solar panels facing different directions, it might be helpful to have them both together in the same chart.
The following (part of) the flow does exactly that. Import this and link it to the second output of the solar forecast node (as in the screenshot):
[{"id":"043b44c03a398e65","type":"ui_chart","z":"d378cf57268ffe49","name":"","group":"c616f24820f867fe","order":9,"width":"24","height":"8","label":"Combined","chartType":"bar","legend":"true","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":true,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":950,"y":660,"wires":[[]]},{"id":"8609aef758bafece","type":"change","z":"d378cf57268ffe49","name":"","rules":[{"t":"set","p":"solar.east","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":640,"wires":[["1df1050aaf92a8e6"]]},{"id":"fa2b24315e845352","type":"change","z":"d378cf57268ffe49","name":"","rules":[{"t":"set","p":"solar.west","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":680,"wires":[["1df1050aaf92a8e6"]]},{"id":"1df1050aaf92a8e6","type":"function","z":"d378cf57268ffe49","name":"Combine multiple inputs","func":"let solar = flow.get('solar') || []\nif (solar.length === 0) {\n return;\n}\n\nlet series = []\nlet data = []\nlet labels = []\n\nfor (const key in solar) {\n for (const s in solar[key][0].series) {\n series.push(solar[key][0].series[s] + ' ' + key)\n }\n for (const d in solar[key][0].data) {\n data.push(solar[key][0].data[d])\n }\n // data.push(solar[key][0].data[0])\n labels = solar[key][0].labels\n\n}\n\nmsg.payload = [{\n series,\n data,\n labels\n }]\n\nmsg.ui_control = {\n options: {\n scales: {\n xAxes: [{\n stacked: true\n }],\n yAxes: [{\n stacked: true\n }]\n }\n }\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":660,"wires":[["043b44c03a398e65"]]},{"id":"c616f24820f867fe","type":"ui_group","name":"Visualisations","tab":"dbb3a86540d4aef4","order":5,"disp":true,"width":"24","collapse":false,"className":""},{"id":"dbb3a86540d4aef4","type":"ui_tab","name":"Solar predictions","icon":"dashboard","disabled":false,"hidden":false}]
Note that this does take the legend label from the name in the change nodes. Adjust the naming there if you want to use different names.
The reason that above is only part of the flow is to prevent you importing the solar forecast subflow twice.
Ah, sorry:
![image](https://private-user-images.githubusercontent.com/167080075/323500118-d2289f4d-ce34-46f3-9208-e0d2a7b77584.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjQ1NDEzMjAsIm5iZiI6MTcyNDU0MTAyMCwicGF0aCI6Ii8xNjcwODAwNzUvMzIzNTAwMTE4LWQyMjg5ZjRkLWNlMzQtNDZmMy05MjA4LWUwZDJhN2I3NzU4NC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwODI0JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDgyNFQyMzEwMjBaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1kNDcyOTJjY2Q4ZWMyMGNjODEwYTU5MmFiNmRkZWVlZjc4MWUxNTY0MTA5NGY5YzViYWExZjg1Njg3NTgwNjI5JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.h77i0Wgbo07lQn8uVSVpk652k1ltnMQANpO98UI7nZk)