Solar Forecast PV

Thanks for this binding. I was already looking for a way to do some solar predictions.
Grabbing the json via http binding was offcourse also an option, but this simplifies the whole process.

I created a rule which is triggered when the jsonraw channel changes to create some graphs (inspired by this post)

// import ForecastSolarPV_RawJSONResponse
val forecastJSON = ForecastSolarPV_RawJSONResponse.state.toString
//logInfo("ForecastSolar", forecastJSON)
// influx uri
val String influxdb_uri = "http://192.168.0.4:8086/write?db=openhab_db&precision=s"

// ZonedDateTime
val ZonedDateTime todayStart = now.withHour(0).withMinute(0).withSecond(0).withNano(0)
val today = now.getDayOfMonth()
val month = now.getMonthValue()
val year = now.getYear()
val hour = now.getHour()
  
//logInfo("ForecastSolar", "currentHour " + currentHour)
  
// json parse
var String watts = transform("JSONPATH", "$.result.watt_hours", forecastJSON) //watts or watt_hours
//logInfo("ForecastSolar", "-" + watts.toString + "-")

// loop over entries
var Integer x = 0
var influx_content = ""
while (x < watts.split(",").length() ) {
  val entry = watts.split(", ").get(x).replace("{","").replace("}","")
  val time = entry.split("=").get(0).toString
  val value = (Double::parseDouble(entry.split("=").get(1)))/1000 // watts to kWh
    
  val formatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
  val dateTime = LocalDateTime.parse(time, formatter).atZone(ZoneId.systemDefault())
  val dateTime_seconds = (dateTime.toEpochSecond)
  val dateHour = dateTime.getHour()
  val dateDay = dateTime.getDayOfMonth()
  //logInfo("ForecastSolar", "-" + dateTime_seconds.toString + "-")
  
  // filter 0 values & hours in the past
  if ((value != 0 && dateHour > hour && dateDay == today) || (value != 0 && dateDay > today)) {
    //logInfo("ForecastSolar", "-" + dateTime.toString + "-")
    influx_content = influx_content + "solarforecast watt_hours=" + value + " " + dateTime_seconds.toString +"\n"
  }
  x++
}

// send to influx
influx_content = influx_content.substring(0, influx_content.length()-2)
//logInfo("ForecastSolar", influx_content.toString)
var responds = sendHttpPostRequest(influxdb_uri, "--data-binary", influx_content, 3000)
logInfo("test", "Influx responds {}", responds)

in Grafana ot looks like this

2 Likes

Solcast tuning is now available in v0.2-alpha in advanced configuration and channels.
Please check in readme solcast tuning section the correct configuration with

  • powerItem - delivering the correct values
  • powerUnit - delivering values with the correct unit
  • DateTime - check openHAB region settings for right time zone

and advanced channels raw-tuning to verify sent data.

Thanks very much for this binding - it has greatly simplified one of my setups, and allowed me to get rid of poorly written spaghetti-code rules!

One minor bit of feedback: in the README, at the Channels sections, the first column is called Channel. However, the values in these cells are not the Channel name - to derive the name one must remove the -channel from the cell value.

So for example:

actual-channel

is not how this Channel should be referred to. It should just be

actual

This confused me for a second when trying to create links in Items files from the Solcast Thing.

Note that the example at the end of the README is correct, omitting the -channel from the Channel names.

1 Like

@curlyel
I think this is a good idea - looks pretty neat in the graph and can be used e.g. to calculate accuracy values using your pv inverter items.

For those who already installed the binding: Things needs to be re-created otherwise the channel won’t appear.

@wars
Please check the Thing Actions from version 0.3. You can query kW values at any point of time. Also kW/h values can be queried between two timestamps.
Note: I needed one reboot after exchanging the bundle in addons folder to be able to access the Actions

@hafniumzinc
You’re right - readme is corrected.

2 Likes

Perfect, exactly this was the intention while asking for it. Many thanks :+1:

1 Like

@weymann : There seems to be a conflict between the Solar Forcast PV Binding and the openHAB cloud connector (see openHAB Cloud "class org.json.JSONObject cannot be cast to class org.json.JSONObject")
I had the same behaviour on my system running on openHAB 3.3.0. I just uninstalled Solar Forecast PV and immediately the cloud connector worked again.

I’m not a programmer, but maybe a dependency issue.
This is the stacktrace when the binding is installed:
2022-08-17 22:06:11.977 [ERROR] [io.socket.thread.EventThread ] - Task threw exception
java.lang.ClassCastException: class org.json.JSONObject cannot be cast to class org.json.JSONObject (org.json.JSONObject is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader ; org.json.JSONObject is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader )
at org.openhab.io.openhabcloud.internal.CloudClient$12.call(CloudClient.java:304) ~[?:?]
at io.socket.emitter.Emitter.emit(Emitter.java:117) ~[bundleFile:?]
at io.socket.client.Socket.onevent(Socket.java:338) ~[?:?]
at io.socket.client.Socket.onpacket(Socket.java:289) ~[?:?]
at io.socket.client.Socket.access$100(Socket.java:24) ~[?:?]
at io.socket.client.Socket$2$2.call(Socket.java:120) ~[?:?]
at io.socket.emitter.Emitter.emit(Emitter.java:117) ~[bundleFile:?]
at io.socket.client.Manager.ondecoded(Manager.java:431) ~[?:?]
at io.socket.client.Manager.access$1600(Manager.java:30) ~[?:?]
at io.socket.client.Manager$7.call(Manager.java:407) ~[?:?]
at io.socket.parser.IOParser$Decoder.add(IOParser.java:105) ~[?:?]
at io.socket.client.Manager.ondata(Manager.java:423) ~[?:?]
at io.socket.client.Manager.access$1000(Manager.java:30) ~[?:?]
at io.socket.client.Manager$2.call(Manager.java:374) ~[?:?]
at io.socket.emitter.Emitter.emit(Emitter.java:117) ~[bundleFile:?]
at io.socket.engineio.client.Socket.onPacket(Socket.java:551) ~[bundleFile:?]
at io.socket.engineio.client.Socket.access$1000(Socket.java:36) ~[bundleFile:?]
at io.socket.engineio.client.Socket$5.call(Socket.java:335) ~[bundleFile:?]
at io.socket.emitter.Emitter.emit(Emitter.java:117) ~[bundleFile:?]
at io.socket.engineio.client.Transport.onPacket(Transport.java:126) ~[bundleFile:?]
at io.socket.engineio.client.Transport.onData(Transport.java:118) ~[bundleFile:?]
at io.socket.engineio.client.transports.WebSocket.access$100(WebSocket.java:24) ~[bundleFile:?]
at io.socket.engineio.client.transports.WebSocket$1$2.run(WebSocket.java:71) ~[bundleFile:?]
at io.socket.thread.EventThread$2.run(EventThread.java:80) [bundleFile:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
at java.lang.Thread.run(Thread.java:829) [?:?]

Would be great if you could resolve this. I liked the forecast, but remote control via app and Alexa is the more important feature :wink:

Thanks!

Thank you @weymann for this very helpful binding.

Unfortunately the binding doesn’t work anymore after upgrading to 3.4.0 M1.

If I try running your example script the following error shows up in openhab.log:

2022-08-19 16:37:01.755 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘9bfc4b356f’ failed: class org.openhab.binding.solarforecast.internal.actions.SolarForecastActions cannot be cast to class org.openhab.binding.solarforecast.internal.actions.SolarForecastActions (org.openhab.binding.solarforecast.internal.actions.SolarForecastActions is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @127438b; org.openhab.binding.solarforecast.internal.actions.SolarForecastActions is in unnamed module of loader org.eclipse.osgi.internal.loader.EquinoxClassLoader @1d3ebce)

I tried to uninstall/install the bundle. During install openhab.log shows the following warning:

2022-08-19 16:35:31.319 [WARN ] [internal.service.FeaturesServiceImpl] - Can’t load features repository mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/3.4.0-SNAPSHOT/xml/features
java.lang.RuntimeException: Error resolving artifact org.openhab.core.features.karaf:org.openhab.core.features.karaf.openhab-core:xml:features:3.4.0-SNAPSHOT: [Could not find artifact org.openhab.core.features.karaf:org.openhab.core.features.karaf.openhab-core:xml:features:3.4.0-SNAPSHOT] : mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/3.4.0-SNAPSHOT/xml/features

Thank you very much.

Cheers,
Sebastian

Did you install the kar or jar file? In this topic both the kar and jar file are included, and given the tag kar I assume ithe marketplace addon will take the kar file. However kar files are version specific, which explains why it doesn’t work. Also the kar file is not needed as this binding doesn’t depend on additional libraries, therefore the jar file should be enough. You could try manually installing the jar version, by downloading it and dropping it in the add-ons directory.

Thanks, this fixed it as you expected.

Thank you very much.

Regards,
Sebastian

Hi Bernd,

thanks for the binding. I’m playing around with it right now using the Forecast.Solar public service. They recently introduced an aditional parameter for damping - see link below. Any chance to get this supported by the binding?

https://doc.forecast.solar/doku.php?id=damping#split_morning_and_evening

Thanks!

… well, there are a few more API URL parameters I’d be interested to explore:

https://doc.forecast.solar/doku.php?id=api

Any chance to provide a freeform edit field by the binding to manipulate the API call?

Thanks for the hint. These parameters are really new. I performed calls with each of them and checked the results.

  • time & time-tz
    are just delivering timestamps in different formats. This shouldn’t be changed by the user. The binding is handling current timestamps in the correct way and it shall not guess around which format is delivered

  • no sun
    Just delivering zero values before and after sunset / sundawn. Binding is already handling this properly

  • inverter
    For each plane you need to specify Kilowatt Peak kwp in configuration. Your inverter can’t handle that? Then please reduce what your inverter can handle or am I wrong?

  • start
    This will jeopardize the calculated values. I you start forecast from e.g. 12:00 the today channel, which shall deliver the total daily forecast, is missing the morning hours.

  • damping
    This parameter is valid! It really delivers different forecast values. Then you would have the possibility to tweak these parameters to get best possible forecast for your system.

My proposal is to add 2 config parameters for morning / evening damping.
The other options will result in errors in the binding calculations plus they don’t have any effect on the forecast values.

1 Like

Hi Bernd,

Yes, the damping parameter(s) are the most interesting ones. The inverter parameter is clipping the peak energy to the max inverter power. I have confirmed that the estimated peak values are reduced to the inverter value. So it might be useful for specific setups.

Thanks!

Hi Bernd,

first of all, thanks for your work at this and also your other bindings.

As Solcast has daily rate limits for the API, it is required to set the refresh interval to 120 min for two sites, which is quite a long time.
I just had a idea how the limited number of API requests might be used more efficient: don’t or far less request the API at night (at least one request during night to get todays forecast would be required) and use those „saved“ requests to refresh more often during day.

Please let me know what you think about that idea.

AFAIK it’s a per hour limit so that won’t help.

120 mins should be fine, remember it’s a free service, if you want more, go pay for it.
Real weather doesn’t change drastically within this time (or that’s in the forecast already), though so the benefit is rather theory than real.

That’s right for Forecast.Solar, but Solcast has a daily limit:

That might be true, if it is, forget about that idea. Then forecast updates every 2 hours are good.
I don’t know if much shorter periods would be sensible as the forecast provider might not update the forecast in this period.

Even though you’ve already withdrawn your proposal, I’d like to add, that I had the same idea and did no update at night time when I’ve inspected the Solcast json by javascript (using the Astro binding to calculate the dawn and dusk).
This - of course - was to “spend” the free api calls at day time only :wink:

Not sure though, if this really improved the prediction for a certain point in time. But if there is any value in increasing the update frequency at day time, this could be an option… :wink:

1 Like

Hi, some more explanations

  • no sun
    Will not add the zeros (for nicer spline renders) at sunrise/sunset, only return available data

  • inverter
    Yes, if you have a (lot) more kWp installed as your inverter can handle, it limits the forecast peaks

  • start=now
    Especially for scenarios when you want to know what for the rest of the day could come

Knut

2 Likes

Thanks for this first hand information! As suggested I’ll adapt the changes in my binding.

Special thanks to you @Forecast.Solar for providing this excellent service. I think each member of the openHAB Community is happy to benefit from your PV production forecast of their home location!

3 Likes