bjornbak
(Christian Bjørnbak)
June 12, 2022, 3:08pm
1
I am considering migration from Home Assistant to openHAB because I do like the automations editor in Home Assistant and the tool support building your own integrations are poor and in Python (which I hate)…
All of this looks better in openHAB but check listing what I need from openHAB I can’t find an equivalent to the Energy Dashboard in HA.
In Energy Dashboard - #9 by marcel_verpaalen was a question for Energy Dashboard like HomeAssistant’s and someone fixed an Energy Summary widget: OH3 Livio Energy Summary Animated
But what about the rest of the Energy Dashboard:
the colored hourly energy consumption based on whether the consumption is fulfilled using my own current production, from grid, discharging the house battery or is from charging the house battery.
a hourly solar production and prediction (the prediction comes from forecast.solar)
and a cost/revenue summary for each of the consumption categories.
Is it all DIY from scratch? and if is it doable?
Example of what it looks like in HA:
rlkoshak
(Rich Koshak)
June 13, 2022, 3:02pm
2
Welcome!
I’ve moved your post to a more appropriate category. The Tutorials and Solutions category is a place to post tutorials, not request them.
OH comes with a fairly flexible charting capability. I would be surprised if what you are looking for isn’t possible but I personally don’t do much with Charts so I can’t offer advice on how to set it up like that. But in general you’ll probably not find much about using just energy search terms since it’s a generic capability. So yes, unless someone has published a widget on the marketplace you’ll probably have to configure this from scratch.
Unfortunately I don’t see a Forecast.solar add-on. Though it does appear to have a fairly straight forward API (see Problem Reading PV Forecast via HTTP Binding from API Forecast.Solar for one example and search the forum for more).
There are also Solcast (see Solcast sendHttpGetRequest ).
However, OH’s charting assumes a time series in the past so it might take some work to generate a forecast chart like that. I don’t think it’s impossible but I’ve not seen it done yet. So this too would be something that needs to be built.
That’s straight forward. Some Items and some rules to run the calculations and a widget to show the current Item’s calculated state.
livio
(livio)
June 13, 2022, 6:28pm
3
dear for graph I used Grafana integrated in OH
for costs…it’s a simple rule with some calculations
later I will publish some pictures
wars
(Ward)
June 13, 2022, 9:33pm
4
I created a small widget which displays my production/consumption/injection per day, month, year. All this is just text. When clicking on one of the items, a OH chart pop-ups. More details and cost calculations are in Grafana.
I’m also very interested in the forecast.solar thing. Hopefully someone van create a binding in the future.
JustinG
(JustinG)
June 13, 2022, 10:08pm
5
I just used the http binding a while back to quick get data from the forecast.solar api.
UID: http:url:450cc0b512
label: Forecast.Solar API
thingTypeUID: http:url
configuration:
authMode: BASIC
ignoreSSLErrors: false
baseURL: API_CALL_HERE
delay: 0
stateMethod: GET
refresh: 600
commandMethod: GET
contentType: application/json
timeout: 3000
bufferSize: 2048
channels:
- id: response
channelTypeUID: http:string
label: API response
description: ""
configuration:
mode: READONLY
But in the end I ended up not really using the thing/item because it was so much easier just to include the API call directing in the rule code I was writing.
wars
(Ward)
June 13, 2022, 10:34pm
6
Actually I so the same for some other stuff. Can you share this rule which you are using?
JustinG
(JustinG)
June 13, 2022, 11:17pm
7
This is with ECMAScript-2021 (the JSScripting add-on):
var now = time.ZonedDateTime.now();
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.SolarForecast');
var runtime = require("@runtime")
var mainPanelUrl = 'API_URL_HERE';
var northPanelUrl = 'API_URL_HERE';
var mainForecast = JSON.parse(actions.HTTP.sendHttpGetRequest(mainPanelUrl));
var northForecast = JSON.parse(actions.HTTP.sendHttpGetRequest(northPanelUrl));
logger.info(JSON.stringify(mainForecast));
var startHour = now.format(time.DateTimeFormatter.ofPattern('yyyy-MM-dd HH:00:00'));
var endHour = now.plusHours(1).format(time.DateTimeFormatter.ofPattern('yyyy-MM-dd HH:00:00'));
var mainMin = mainForecast.result.watts[startHour] || 0;
var mainMax = mainForecast.result.watts[endHour] || 0;
var northMin = northForecast.result.watts[startHour] || 0;
var northMax = northForecast.result.watts[endHour] || 0;
var mainEstimate = mainMin + ((mainMax - mainMin) * now.minute() / 60);
var northEstimate = northMin + ((northMax - northMin) * now.minute() / 60);
var totalEstimate = Math.round(mainEstimate + northEstimate);
logger.info(`Main cells: ${mainMin} - ${mainMax}, North cells: ${northMin} - ${northMax}, Current estimate at ${now.minute()} - ${totalEstimate} (${totalEstimateAdj} adjusted)`);
items.getItem('SolarForecast_Watts').sendCommand(totalEstimate);
var mainMinH = mainForecast.result.watt_hours[startHour] || 0;
var mainMaxH = mainForecast.result.watt_hours[endHour] || 0;
var northMinH = northForecast.result.watt_hours[startHour] || 0;
var northMaxH = northForecast.result.watt_hours[endHour] || 0;
var mainEstimateH = mainMinH + ((mainMaxH - mainMinH) * now.minute() / 60);
var northEstimateH = northMinH + ((northMaxH - northMinH) * now.minute() / 60);
var totalEstimateH = Math.round(mainEstimateH + northEstimateH);
logger.info(`Main cells: ${mainMinH} - ${mainMaxH}, North cells: ${northMinH} - ${northMaxH}, Current estimate at ${now.minute()} - ${totalEstimateH}`);
items.getItem('SolarForecast_WattHours').sendCommand(totalEstimateH);
wars
(Ward)
June 14, 2022, 11:27am
8
thanks!
If I understand it well, you only store the data for the specific hour (now). And not for all future hours the coming 48 hours (which I get back with the public API).
I am planning to inject this data once a day to my influxdb to have a nice forecast graph above my actual production. Or is this not the way to go?
Hi ,
Is possible to share the code for the widget and graphs ?
Thanks
Artur
wars
(Ward)
June 14, 2022, 3:41pm
10
I created one widget, which can show me data of today, yesterday, this month, last month or this year. This can be modified via a prop:
All the values are calculated via rules and added to items. All these items have the same suffixes (today, yesterday, thisMonth…) to make it easier.
If I choose today , the widged will also show my battery level and rainwater tank.
So this widget is certainly not useable for everybody, cause I made it specific for my needs (and I’m not a widget expert at all)
uid: solarman_energy
tags: []
props:
parameters:
- default: today
description: Time for card. Must be today, yesterday, thisMonth, prevMonth or thisYear
label: Period
name: period
required: false
type: TEXT
pattern: today|yesterday|thisMonth|prevMonth|thisYear
parameterGroups: []
timestamp: Jun 8, 2022, 10:06:36 PM
component: f7-card
config:
style:
border-radius: var(--f7-card-expandable-border-radius)
box-shadow: 5px 5px 10px 1px rgba(0,0,0,0.1)
margin-left: 5px
margin-right: 5px
noShadow: false
padding: 0px
title: '="Energy " + (props.period == "thisMonth" ? "this month" : props.period == "prevMonth" ? "previous month": props.period == "thisYear" ? "this year": props.period)'
slots:
default:
- component: f7-row
config:
style:
align-items: left
justify-content: left
margin-left: 10px
margin-top: 10px
visible: true
slots:
default:
- component: oh-icon
config:
color: lightgreen
height: 30
icon: iconify:mdi:solar-power-variant
style:
margin-right: 10px
- component: Label
config:
style:
font-size: 17px
font-weight: 700
margin-left: 0px
text: Solar Panels
- component: f7-row
config:
style:
align-items: center
justify-content: center
margin-left: 20px
margin-top: 10px
visible: true
slots:
default:
- component: f7-col
config:
class:
- display-flex
- justify-content-left
slots:
default:
- component: oh-icon
config:
color: green
height: 30
icon: iconify:mdi:solar-power
style:
margin-right: 10px
- component: oh-link
config:
action: analyzer
actionAnalyzerItems: =['solarman_CumulativeProductionActive_' + props.period]
color: white
style:
//font-weight: bold
font-size: 20px
margin: 0px 0px
text: =items['solarman_CumulativeProductionActive_' + props.period].state
- component: f7-col
config:
class:
- display-flex
- justify-content-left
slots:
default:
- component: oh-icon
config:
color: red
height: 30
icon: iconify:mdi:flash
style:
margin-right: 10px
- component: oh-link
config:
action: analyzer
actionAnalyzerItems: =['solarman_CumulativeConsumption_' + props.period]
color: white
style:
//font-weight: bold
font-size: 20px
margin: 0px 0px
text: =items['solarman_CumulativeConsumption_' + props.period].state
- component: f7-row
config:
style:
align-items: center
justify-content: center
margin-left: 20px
margin-top: 10px
visible: '=props.period == "today" ? true : false'
slots:
default:
- component: f7-col
config:
class:
- display-flex
- justify-content-left
slots:
default:
- component: oh-icon
config:
color: green
height: 30
icon: iconify:mdi:transmission-tower-import
style:
margin-right: 10px
- component: oh-link
config:
action: analyzer
actionAnalyzerItems: =['solarman_DailyGridFeedin']
color: white
style:
//font-weight: bold
font-size: 20px
margin: 0px 0px
text: =items['solarman_DailyGridFeedin'].state + ' kWh'
- component: f7-col
config:
class:
- display-flex
- justify-content-left
slots:
default:
- component: oh-icon
config:
color: red
height: 30
icon: iconify:mdi:transmission-tower-export
style:
margin-right: 10px
- component: oh-link
config:
action: analyzer
actionAnalyzerItems: =['solarman_DailyEnergyPurchased']
color: white
style:
//font-weight: bold
font-size: 20px
margin: 0px 0px
text: =items['solarman_DailyEnergyPurchased'].state + ' kWh'
- component: f7-row
config:
style:
align-items: center
justify-content: center
margin-left: 30px
margin-top: 10px
visible: '=props.period == "today" ? true : false'
slots:
default:
- component: f7-col
config:
class:
- display-flex
- justify-content-left
slots:
default:
- component: oh-icon
config:
color: purple
height: 30
icon: iconify:mdi:home-battery
style:
margin-right: 10px
- component: oh-link
config:
action: analyzer
actionAnalyzerItems: =['solarman_SoCBatteryPack1']
color: white
style:
//font-weight: bold
font-size: 20px
margin: 0px 0px
text: =items['solarman_SoCBatteryPack1'].state + ' %'
- component: f7-row
config:
style:
align-items: left
justify-content: left
margin-left: 10px
margin-top: 10px
visible: true
slots:
default:
- component: oh-icon
config:
color: yellow
height: 25
icon: iconify:mdi:meter-electric
style:
margin-right: 10px
- component: Label
config:
style:
font-size: 17px
font-weight: 700
margin-left: 0px
text: Electricity
- component: f7-row
config:
style:
align-items: center
justify-content: center
margin-left: 20px
margin-top: 10px
visible: true
slots:
default:
- component: f7-col
config:
class:
- display-flex
- justify-content-left
slots:
default:
- component: oh-icon
config:
color: green
height: 30
icon: iconify:mdi:transmission-tower-import
style:
margin-right: 10px
- component: oh-link
config:
action: analyzer
actionAnalyzerItems: =['mqtt_dsmr_electricityReturned_' + props.period]
color: white
style:
//font-weight: bold
font-size: 20px
margin: 0px 0px
text: =items['mqtt_dsmr_electricityReturned_' + props.period].state
- component: f7-col
config:
class:
- display-flex
- justify-content-left
slots:
default:
- component: oh-icon
config:
color: red
height: 30
icon: iconify:mdi:transmission-tower-export
style:
margin-right: 10px
- component: oh-link
config:
action: analyzer
actionAnalyzerItems: =['mqtt_dsmr_electricityDelivered_' + props.period]
color: white
style:
//font-weight: bold
font-size: 20px
margin: 0px 0px
text: =items['mqtt_dsmr_electricityDelivered_' + props.period].state
- component: f7-row
config:
style:
align-items: left
justify-content: left
margin-left: 10px
margin-top: 10px
visible: true
slots:
default:
- component: oh-icon
config:
color: orange
height: 25
icon: iconify:mdi:meter-gas
style:
margin-right: 10px
- component: Label
config:
style:
font-size: 17px
font-weight: 700
margin-left: 0px
text: Gas
- component: f7-row
config:
style:
align-items: center
justify-content: center
margin-left: 30px
margin-top: 10px
visible: true
slots:
default:
- component: f7-col
config:
class:
- display-flex
- justify-content-left
slots:
default:
- component: oh-icon
config:
color: orange
height: 30
icon: iconify:mdi:meter-gas
style:
margin-right: 10px
- component: oh-link
config:
action: analyzer
actionAnalyzerItems: =['mqtt_dsmr_gas_' + props.period]
color: white
style:
//font-weight: bold
font-size: 20px
margin: 0px 0px
text: =items['mqtt_dsmr_gas_' + props.period].displayState
- component: f7-row
config:
style:
align-items: left
justify-content: left
margin-left: 10px
margin-top: 10px
visible: true
slots:
default:
- component: oh-icon
config:
color: lightblue
height: 30
icon: iconify:mdi:water
style:
margin-right: 10px
- component: Label
config:
style:
font-size: 17px
font-weight: 700
margin-left: 0px
text: Water
- component: f7-row
config:
style:
align-items: center
justify-content: center
margin-left: 20px
margin-top: 10px
visible: true
slots:
default:
- component: f7-col
config:
class:
- display-flex
- justify-content-left
slots:
default:
- component: oh-icon
config:
color: lightblue
height: 30
icon: iconify:mdi:cup-water
style:
margin-right: 10px
- component: oh-link
config:
action: analyzer
actionAnalyzerItems: =['mqtt_pulse_water' + (props.period).substring(0, 1).toUpperCase() + (props.period).substring(1)]
color: white
style:
//font-weight: bold
font-size: 20px
margin: 0px 0px
text: =items['mqtt_pulse_water' + (props.period).substring(0, 1).toUpperCase() + (props.period).substring(1)].displayState
- component: f7-col
config:
class:
- display-flex
- justify-content-left
visible: '=props.period == "today" ? true : false'
slots:
default:
- component: oh-icon
config:
color: lightblue
height: 30
icon: iconify:mdi:water-well
style:
margin-right: 10px
- component: oh-link
config:
action: analyzer
actionAnalyzerItems: =['rainwater_percent']
color: white
style:
//font-weight: bold
font-size: 20px
margin: 0px 0px
text: =items['rainwater_percent'].displayState
- component: f7-card-footer
slots:
default:
- component: Label
config:
text: '="Last update: " + dayjs(items.solarman_lastupdate_.state).fromNow()'
JustinG
(JustinG)
June 14, 2022, 4:03pm
12
That’s correct. I found that the forecast.solar predictions weren’t quite as accurate as I had hoped for my system. However, the forecast values are refined throughout the day so this was an attempt to see if the values got closer to my system production as the day went on by continually updating the values and doing a little linear interpolation between the hour values.
That may be a fine way to go for your system, I think this isn’t so much a right/wrong choice as a personal decision. I even tried building a custom estimate from the astro sun data which was slightly better. In the end I dropped getting a solar estimate from my todo list and went on to other projects.
If you’re planning on just one call a day ans processing the data in a rule to push to influxDB then the http binding is probably the (ever-so-slightly) easier way to do go.
system
(system)
Closed
July 26, 2022, 8:04am
13
This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.