This binding provides data from Solar Forecast services. Use it to estimate your daily production, plan electric consumers like Electric Vehicle charging, heating or HVAC. Look ahead the next days in order to identify surplus / shortages in your energy planning.
Would love to test this. Iâm on OpenHabian 3.3.0 - Release Build on a Pi4. So, should i just drop the jar-file in the /usr/share/openhab/addons/ dir, just as with other bindings that are not (yet) in the Marketplace? If so -and please forgive my ignorance-, whatâs with the .kar file?
I directly checked Marketplace after this post and the binding is present
Honestly I donât know the purpose of the 2 packaging formats but I think kar is the preferred one for openHAB.
If you donât use the Marketplace installation either pick jar or kar and drop it into the mentioned /usr/share/openhab/addons/ folder and youâll be fine!
Yes, test version is already running in my system and as soon as itâs stable enough on my side itâll be part in an upcoming version update in the Marketplace.
Thanks Bernd for sharing this binding. Iâm about to try it once being back from vacation
Happy, that you took the effort for simplifying this solar prediction stuff. I did something similar just by using the http binding getting the Solcast json and calculate the predicted solar production by a rule.
Your approach simplifies this a lot. And according to the other posts here and in other threads, there seems to be some demand for such a binding.
Mind raising a pull request for it to get it merged as official binding once you are convinced by your codeâs maturity?
One additional thing: Would you add a channel for predicted âcurrent solar powerâ which should provide the average power for the current time.
Example for Solcast (as they provide the prediction in 30 mins resolution):
<Solar yield for current half hour> * 2 = <current predicted power>
Bonus: You could even interpolate values by considering last+current+next half hour to provide intermediate values as you already seem to do for some of your existing channels.
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)
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.
@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.
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
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:
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 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?