Giter Site home page Giter Site logo

Comments (44)

davidusb-geek avatar davidusb-geek commented on July 18, 2024 1

Hi, I've just updated this implementation as it was certainly not complete when I posted those results in my previous post.
Actually I realized that a PV curtailment variable is needed to implement this. I guess that this type of behavior is internally implemented in this type of inverter. Or that the PV system and the battery are well sized to avoid curtailement.

In any case to test this I have the same inputs that in my previous post but I have now multiplied the PV forecast by 2 to force the curtailment and to check the nominal power limitation of the hybrid inverter. I again considered a period of negative prod prices. The nominal power of the tested hybrid inverter is 5 kW.

Now the constraint looks like this:
$P_{hybrid} = P_{PV} - P_{curtailment} + P_{bat}^{pos} + P_{bat}^{neg} \leq P_{hybrid}^{nominal}$

Here are my inputs:
image
image

And the main results:
image

With the results table:

image

As we can see we now have P_hybrid_inverter and a P_PV_curtailment variables. The curtailment effectively activates on the period of negative prod prices and the P_hybrid_inverter never exceeds the nominal power of 5 kW even when the PV production is higher than 5 kW. The system converges to a solution where no power is injected to the grid during negative prod prices.

What do you think?

For reference this is what it looks like when setting inverter_is_hybrid = False.
So this is to check the behavior of curtailment, I think that it is applied properly here and again no power is injected to the grid during negative prod prices.

image

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024 1

I'll wait for your feedback but I think that this solves this issue.
One thing is that for now I'm using the model of the inverter defined in the configuration file to obtain the nominal power of the inverter, which is needed by the defined new constraints.
This can be a problem for people using solar.forecast, soclast or passing their own PV forecast data.
However the solution will be to properly define this entry in the configuration with at least an inverter model with at least similar nominal power as yours. I've developed a little app to help find the models in the database: https://emhass-pvlib-database.streamlit.app/

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024 1

Let me have a go at testing. I'm going to try running this locally (instead of trying to update the EMHASS add-on) and how I go back on a command line.

Sorry I didn't gave much further explanation.
This is not released on any add-on version, so you will only find the base code on a development git branch. There is a script that you can use on that branch.
In a machine with Python installed the steps are: clone the repo, set an environment, switch to dev branch, launch the script...

git clone https://github.com/davidusb-geek/emhass.git
cd emhass
python -m venv .venv
source .venv/bin/activate
python setup.py install
git checkout davidusb-geek/dev/hybrid_inverter_def_seq
python scripts/script_debug_optim.py

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024 1

Parlez vous Anglais?

Oui c'était bien de l'anglais ;-)

from emhass.

purcell-lab avatar purcell-lab commented on July 18, 2024

I have my EMHASS forecasts (on the left) aligned with my actual readings (on the right) so I can debug these types of issues

Screenshot_20240308-160452

The EMHASS forecasts should always be in balance, if Optimal.

Grid +  PV + Battery = Load (+ deferrable loads)

It's not clear from your example above what are the four EMHASS forecasts.

from emhass.

Deztak avatar Deztak commented on July 18, 2024

The bottom row are actuals, second bottom row is the planned. I’m re-running the option and publish every few minutes, basically when there is new pricing or Solar forecasts.

Most of the first three rows are actuals, total power is the sum of all of the power sources (actuals) and the percentages are the percentage of the total power that is being sourced (first row) and drawn (second row)

So EMHASS Grid Power is -9,679.09 W and this is just states.p_grid_forecast
EMHASS PV Power is states.p_pv_forecast

I do have an output that shows the sum of the power sources from EMHASS and it was over 13,000 W … if there is an inverter power limit in the config then I’ve missed it but, I think this could be solved with an Inverter power limit as the batteries can be charge with up to 15,000 W from the PV on the DC circuit but the AC circuit is always limited to 10,000 W whether it’s powering the house or feeding the grid. When it’s recharging it will trip my 63amp circuit breaker at about 15,200 W so I could in theory power the house with 5,200 W while recharging the batteries from grid with 10,000 W … but tripping the circuit breaker too often has lead me to only allow 13,000 W that way turning on a 2,000W oven or kettle won’t trip the circuit breaker.

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024

Use the template editor in developer tools to share your actual curl command and the actual data that you are passing to each enpoint call. Also share the details of your setup/config as asked on the issue template. Otherwise it is difficult to provide help.

from emhass.

Deztak avatar Deztak commented on July 18, 2024

Mark helped me out via an Amber-Home Assistant Facebook group to get some rest sensors setup that pull data from Solar.Forecast as well as pushing data to EMHASS. Unfortunately I can’t seem to copy-paste from the Mobile UI in Samba or access the add-on tabs.

If I end up not being able to get to sleep then I’ll copy-paste it all here but, if the issue is the user then I’m thinking it’s in the config. I messed about with it a bit, trying to get the EMHASS outputs to be right. SolarEdge setup the batteries with a charge limit of 11,400W as this is basically the theoretical peak PV power of my setup. I do have three of their 9.7kVA batteries, with a theoretical max DC charge rate of 15,000W (so I have spare capacity in my DC circuit)

I had the charge and discharge rates set to 10,000 W but then EMHASS was feeding back to the grid while the feed-in price was forecast to be negative, so I bumped up the charge rate to 11,400 W and that solved that issue but if I bumped up the discharge rate to 11,400 W then it would predict it discharging at 11,400 W … as that’s not possible I put it back to 10,000 W but, EMHASS seems to think the inverter can push out peak PV + peak battery discharge power at the same time.

Below is a plot of the actual total power and EMHASS total power. Below that is a plot of EMHASS PV, Batt, Grid & Load with the same time period actuals. Note in the processed data for the gauge display I need to negate the actual grid power as I have +ve for drawn power for each power source.

image image

from emhass.

Deztak avatar Deztak commented on July 18, 2024

My rest commands:
Copy-pasted from stuff Mark sent me on facebook as I tried to get his code from the help docs to work and struggled a lot. I don't use SolCast

rest_command:
post_mpc_optim_solcast:
url: http://homeassistant.local:5000/action/naive-mpc-optim
method: POST
content_type: 'application/json'
payload: >-
{ "pv_power_forecast":{{states('sensor.solcast_24hrs_forecast')}},"load_cost_forecast":{{states('sensor.amber_gen_price_forecast')}},"prod_price_forecast":{{states('sensor.amber_prod_price_forecast')}},"prediction_horizon":{{states('sensor.solcast_24hrs_forecast')|from_json|count}},"soc_init":{{(states('sensor.med_battery_charge')|float(0)/100)|round(2)}},"soc_final":{{float(0.15)|round(2)}} }
dayahead_optim:
url: http://homeassistant.local:5000/action/dayahead-optim
method: POST
content_type: 'application/json'
payload: >-
{}
publish_data:
url: http://homeassistant.local:5000/action/publish-data
method: POST
content_type: 'application/json'
payload: >-
{}

The data passed through the 'post_mpc_optim_solcast' function looks like:

{
"pv_power_forecast": [
3722,
4558,
5324,
6030,
6646,
7180,
7562,
7790,
7868,
7924,
7886,
7694,
7346,
6856,
6248,
5534,
4726,
3852,
3046,
2300,
1536,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"load_cost_forecast": [
0.13,
0.11,
0.14,
0.13,
0.07,
0.04,
0.04,
0.04,
0.04,
0.04,
0.04,
0.33,
0.35,
0.36,
0.38,
0.39,
0.39,
0.39,
0.41,
0.41,
0.45,
0.45,
0.46,
0.19,
0.19,
0.19,
0.18,
0.19,
0.19,
0.2,
0.19,
0.2,
0.19,
0.19,
0.19,
0.16
],
"prod_price_forecast": [
0.04,
0.02,
0.04,
0.02,
-0.04,
-0.06,
-0.07,
-0.07,
-0.07,
-0.07,
-0.07,
0.24,
0.27,
0.28,
0.29,
0.31,
0.31,
0.3,
0.32,
0.32,
0.36,
0.36,
0.37,
0.09,
0.09,
0.09,
0.08,
0.09,
0.09,
0.09,
0.09,
0.09,
0.09,
0.09,
0.09,
0.07
],
"prediction_horizon": 36,
"soc_init": 0.17,
"soc_final": 0.15
}

from emhass.

Deztak avatar Deztak commented on July 18, 2024

EMHASS add-in config file:
Note, I have no deferrable loads setup. Mark recommended that I try a shelly device to setup my hot water as a deferrable load. I'm still looking into this. My inverter and solar panels are not listed in the csv.

logging_level: INFO
costfun: profit
sensor_power_photovoltaics: sensor.solar_power_w
sensor_power_load_no_var_loads: sensor.consumption_power_w
set_total_pv_sell: false
set_nocharge_from_grid: false
set_nodischarge_to_grid: false
maximum_power_from_grid: 10000
number_of_deferrable_loads: 1
list_nominal_power_of_deferrable_loads:

  • nominal_power_of_deferrable_loads: 1
    list_operating_hours_of_each_deferrable_load:
  • operating_hours_of_each_deferrable_load: 0
    list_start_timesteps_of_each_deferrable_load:
  • start_timesteps_of_each_deferrable_load: 0
    list_end_timesteps_of_each_deferrable_load:
  • end_timesteps_of_each_deferrable_load: 0
    list_peak_hours_periods_start_hours:
  • peak_hours_periods_start_hours: "00:00"
    list_peak_hours_periods_end_hours:
  • peak_hours_periods_end_hours: "00:00"
    list_treat_deferrable_load_as_semi_cont:
  • treat_deferrable_load_as_semi_cont: true
    list_set_deferrable_load_single_constant:
  • set_deferrable_load_single_constant: false
    load_peak_hours_cost: 0.1907
    load_offpeak_hours_cost: 0.1419
    photovoltaic_production_sell_price: 0.065
    list_pv_module_model:
  • pv_module_model: CSUN_Eurasia_Energy_Systems_Industry_and_Trade_CSUN295_60M
    list_pv_inverter_model:
  • pv_inverter_model: Fronius_International_GmbH__Fronius_Primo_5_0_1_208_240__240V_
    list_surface_tilt:
  • surface_tilt: 32
  • surface_tilt: 36
    list_surface_azimuth:
  • surface_azimuth: 34
  • surface_azimuth: 216
    list_modules_per_string:
  • modules_per_string: 16
  • modules_per_string: 16
    list_strings_per_inverter:
  • strings_per_inverter: 1
  • strings_per_inverter: 1
    set_use_battery: true
    battery_nominal_energy_capacity: 29100
    battery_discharge_power_max: 8000
    battery_charge_power_max: 11399
    battery_discharge_efficiency: 0.95
    battery_charge_efficiency: 0.95
    battery_minimum_state_of_charge: 0.12
    battery_maximum_state_of_charge: 1
    battery_target_state_of_charge: 0.1
    weather_forecast_method: solar.forecast
    load_forecast_method: naive

from emhass.

Deztak avatar Deztak commented on July 18, 2024

Note in today's plan @ 1700 I have 8,512 W in P_grid_neg and 3,813 W in P_load ... so the total power through the inverter per the plan is 12,325 W

newplot (2)

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024

I don't see a total inverter of 12 kW. According to that graph the maximum power through your inverter is around 8 kW peak. I really don't see the issue here.

from emhass.

Deztak avatar Deztak commented on July 18, 2024

So looking at it from a power source perspective when my SolarEdge inverter is in "Discharge to maximise export" mode it outputs all available pv and batt power to the grid. At 1700 in the plot the pv power is about 5kW and the battery power is about 8kW, so the combined power is still more than the peak output of the inverter.

And as above, from a load perspective, my inverter can't power the grid independantly of the load, so as above the inverter outputs 10kW and what isn't consumed by the load goes to the grid ... with a load forecast of 3.8kW the grid export cannot be above 6.2kW (while the forecast is 8.5kW)

from emhass.

purcell-lab avatar purcell-lab commented on July 18, 2024

I suspect your issue maybe that you have a DC coupled battery, so only the one inverter is servicing both PV and battery. So whilst your settings for your PV inverter can export 10 kW, your settings also state your battery (inverter) can discharge 8 kW. However your system is only capability of exporting a total of 10 kW, in any combination of battery and PV.

I have an AC coupled battery, so in effect I have two inverters; battery inverter and a PV inverter that can function independently. So in effect my maximum export is battery inverter (15 kW) + PV inverter (15 kW). This is how EMHASS models batteries and PV inverters.

from emhass.

Deztak avatar Deztak commented on July 18, 2024

Yes, that makes the most sense for where my setup isn't as EMHASS assumes my setup is configured.

@purcell-lab

I suspect your issue maybe that you have a DC coupled battery, so only the one inverter is servicing both PV and battery. So whilst your settings for your PV inverter can export 10 kW, your settings also state your battery (inverter) can discharge 8 kW. However your system is only capability of exporting a total of 10 kW, in any combination of battery and PV.

the EMHASS forecast only makes sense to me if you have an inverter for the batteries and another for the pv … but with only one inverter with a common DC connection bus, the inverter is the bottleneck.

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024

Couldn't this issue be solved by a maximum power from grid settings AND a maximum power to grid setting?

from emhass.

purcell-lab avatar purcell-lab commented on July 18, 2024

Couldn't this issue be solved by a maximum power from grid settings AND a maximum power to grid setting?

I don't that that work resolve the issue.

Power from grid could be upto 10 kW through the inverter to charge battery + what ever amount of household load an additional 5, 10, 15 kW. Typically the network limits single phase households to 15 kW (63 A) - 20 kW (80 A)

Power to grid would be a maximum of 10 kW (through inverter mix of battery + solar), but if household load is 2 kW then max to grid is 8 kW, if household load is 5 kW then max to grid is 5 kW, ...

I think within EMHASS DC coupled batteries sharing an inverter need to be calculated differently taking into account the constraint of only having one inverter.

from emhass.

Deztak avatar Deztak commented on July 18, 2024

Couldn't this issue be solved by a maximum power from grid settings AND a maximum power to grid setting?

I did try this but, my inverter CAN charge the batteries with 10kW and still support about 5kW of house load before tripping the 63amp breaker. I have a calculator that goal seeks on 13kW total draw from the grid. I tried goal sealing on 14kW but have too many appliances that can draw over 1kW and I have too many breaker trips.

So the system was overcharging at higher prices and it seemed to be costing me more than the current issue as that energy could have cost nothing if the pv provided it.

I think the simple solution would be to have a ‘maximum power to grid’ along with the current ‘maximum power from grid’ rather than assuming both are the same limit. Acknowledging that you have a good mix of optional and required variables already, I don’t know if it should be an optional or required input. I am biased but, maybe it should be ‘required’?

I think I could do a work-around where:

if p_grid_forecast < 0 then:
set max_from_grid = int(10000)
else
set max_from_grid = int(13000)

then of course I’d need to lookup the docs to see if I can include this in my optim rest command.

from emhass.

Deztak avatar Deztak commented on July 18, 2024

On this topic, I also have another code that checks if I’m better of charging from the grid or just charging from Solar and having the house load come from the grid. Where:
If p_pv > 13kW - p_load then
Call script: set_charge_solar_only
Else
Call script: set_charge_solar_and_grid

… so I have actually achieved a total power exceeding 15kW but I had about 6kW of house load due to my massive aircon struggling with the heatwave conditions.

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024

if p_grid_forecast < 0 then:
set max_from_grid = int(10000)
else
set max_from_grid = int(13000)

Ok this seems like a condition that should be implemented in the code to properly support this special configuration of the same inverter for both PV and battery. Do you agree @purcell-lab ?

Well I think that this is exactly waht you meant with this:

I think within EMHASS DC coupled batteries sharing an inverter need to be calculated differently taking into account the constraint of only having one inverter.

from emhass.

philjohn avatar philjohn commented on July 18, 2024

Couldn't this issue be solved by a maximum power from grid settings AND a maximum power to grid setting?

As Deztalk said - not for this case, but for another case where you have a limit on the amount of power you can send back to the grid, which is lower than the amount you can pull, that would be a useful change.

from emhass.

Deztak avatar Deztak commented on July 18, 2024

I agree, I just don’t know what would be involved as I don’t know the code. From reading the API info for my inverter, it has heaps of different operating modes such as limited energy return per day and proportion of energy generated per day. It even seems to have an ability to call on a backup generator, I guess for applications where you are off grid.

The output plots have to_grid and from_grid power separated, so logically speaking the code does breakup the grid power at some point … but is this done before or after the optimisation?

How much is involved in adding it to the config? Or should it be passed to EMHASS via the CURL or REST_command? Yes, not having it in the config file may make it harder, but it’s potentially a feature for more advanced users … so maybe adding it to the config would make the initial setup that little bit more complex for the average user and thus turn them away… I don’t know any of the answers to these questions, so it’s up to the best judgement of the devs and I’ll respect the decision they make as they would also have to deal with the consequence of other complaining about these potential issues.

I am very grateful for this, the sales team lead me to believe that SolarEdge does this optimisation for us and after trying for over 12 months to get something similar coded, I never broke even over a billing cycle. Currently I am about $85 in the black in the first billing cycle with EMHASS. Thankyou Devs.

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024

The output plots have to_grid and from_grid power separated, so logically speaking the code does breakup the grid power at some point … but is this done before or after the optimisation?

It is braked down before the optimization to convert the problem to a linear one.

How much is involved in adding it to the config? Or should it be passed to EMHASS via the CURL or REST_command? Yes, not having it in the config file may make it harder, but it’s potentially a feature for more advanced users … so maybe adding it to the config would make the initial setup that little bit more complex for the average user and thus turn them away… I don’t know any of the answers to these questions, so it’s up to the best judgement of the devs and I’ll respect the decision they make as they would also have to deal with the consequence of other complaining about these potential issues.

I've marked this as a necessary enhancement and we will add support for this in the future, as is not even a strange use case. I guess that in the future with more batteries people will have this configuration more often.
We just need to add a boolean in the configuration to state that we have one single inverter for PV and batteries and based on this we need to add some conditions and constraints before the optimization.

I am very grateful for this, the sales team lead me to believe that SolarEdge does this optimisation for us and after trying for over 12 months to get something similar coded, I never broke even over a billing cycle. Currently I am about $85 in the black in the first billing cycle with EMHASS. Thankyou Devs.

Cheers, glad to hear!

from emhass.

Deztak avatar Deztak commented on July 18, 2024

Thanks Davidusb.

With the grid in this part of NSW there is a 10kW inverter limit, anymore and we had to register it as a virtual power plant and other BS costs and delays would be added. So I hesitated ALOT as, I would have to decide on whether to have a 4kW inverter on my (then) 6.6kW array and a 6kW inverter on my 29.1kWh of batteries or put leave the old inverter and have a smaller inverter for the batteries.

None of it really worked out to my setup being any where near cost positive. Then they told me about the setup I eventually got and I went all-in … max number of the biggest batteries and added 5.7kW of panels to my Solar array.

I don’t know if they’ll be more common but, within the constraints put on me by AusGrid, I was either never getting batteries or I’d get the setup I now have.

I’m hoping that Amber will payout my bill credits in a way that I can “buy you a coffee” with that payout.

from emhass.

kcoffau avatar kcoffau commented on July 18, 2024

I setup a hard limit in HA to only allow 10KW export, even when EMHASS instructs more. Its means EMHASS is wrong for periods, but revaluates every 5 mins, so in the wash, its OK.

Agree, grid limits would be an awesome variable to add. both inbound and outbound which includes loads, solar and battery.

from emhass.

Deztak avatar Deztak commented on July 18, 2024

I setup a hard limit in HA to only allow 10KW export, even when EMHASS instructs more. Its means EMHASS is wrong for periods, but revaluates every 5 mins, so in the wash, its OK

this follows my experience too, but I noticed that I was losing more money due to less Solar being directly exported this way and I was better off with just tolerating not fully draining the battery while prices are high.

from emhass.

altonius avatar altonius commented on July 18, 2024

I look forward to a DC-Coupled battery option, thanks everyone for looking into this and explaining exactly what I'm experiencing.

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024

I setup a hard limit in HA to only allow 10KW export, even when EMHASS instructs more. Its means EMHASS is wrong for periods, but revaluates every 5 mins, so in the wash, its OK.

Agree, grid limits would be an awesome variable to add. both inbound and outbound which includes loads, solar and battery.

These grid limits were already added recently. It is now possible to set these in the configuration file:

P_from_grid_max: 9000 # The maximum power that can be supplied by the utility grid in Watts
  P_to_grid_max: 9000 # The maximum power that can be supplied to the utility grid in Watts

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024

I will try to work very soon on adding support for hybrid inverters.

from emhass.

altonius avatar altonius commented on July 18, 2024

I will try to work very soon on adding support for hybrid inverters.

Happy to help out with any testing when you're close to finishing this.

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024

I will try to work very soon on adding support for hybrid inverters.

Happy to help out with any testing when you're close to finishing this.

Hi, I've just implemented a first solution.
The results seems coherent to me.
I solved this by adding an additional constraint like this:
$P_{hybrid}=P_{PV}+P{bat}^{pos}+P{bat}^{neg}\leq P_{hybrid}^{nominal}$
Where $P_{hybrid}^{nominal}$ is the nominal power of the hybrid inverter.

I will gladly use your help @altonius or anyone willing to provide help analyzing this.
To test this you need to clone this branch https://github.com/davidusb-geek/emhass/tree/davidusb-geek/dev/hybrid_inverter_def_seq
Then launch the script in: scripts\script_debug_optim.py

The input data: artificially added negative prod prices
image
image

The optimization results:
image

The results table:

image
image

Does these seem logical to you?

from emhass.

altonius avatar altonius commented on July 18, 2024

Let me have a go at testing. I'm going to try running this locally (instead of trying to update the EMHASS add-on) and how I go back on a command line.
The calculations look correct to me. I just need to get my head around how the calculation handles the different scenarios.

from emhass.

Deztak avatar Deztak commented on July 18, 2024

For reference this is what it looks like when setting inverter_is_hybrid = False.

I'm struggling to figure out where to put "inverter_is_hybrid = False" and I can't see anything in the docs/readme/configUI for v0.9.1

I'm using the add-in and I'm getting the feeling that's what I'm doing wrong ...

--- edit ---

apologies just found ... now confused as to how to use it :P
https://github.com/davidusb-geek/emhass/tree/davidusb-geek/dev/hybrid_inverter_def_seq

--- edit 2 ---
I installed HASSIO onto a separate x64 machine ...
https://www.home-assistant.io/installation/generic-x86-64

Seems that there should be some sort of "docker" method but, I can't figure it all out right now ... but this looks pretty promising. Given the weather here in NSW and that about 40% of my array faces WSW I'm unlikely to have this issue again for a little while. However it does look like you have the excess solar going into the batteries rather than to the grid which is what the forecast was saying previously and thus my controller that primarily looked at the power to the grid to determine if it should set the inverter to maximise export wouldn't be dumping 10kW back to the grid during negative feed-in pricing anymore.

So based on your data plots, it looks like you've solved it.

from emhass.

altonius avatar altonius commented on July 18, 2024

I'm not having much luck with setting up my test environment, I'm going to go through the table and see if they all make sense.

I think @Deztak above is looking at exporting scenarios. I'm looking at my current import scenarios (per the image).

If I configure battery_charge_power_max to 5000w emhass isn't able to combine both the PV and Grid to exceed this. As I use p_batt as an input to guide my charge/discharge automations, it gets tricky, so I have to increase my charge max during the day, and then decrease it overnight when I'm only going to import from the grid.

image

from emhass.

Deztak avatar Deztak commented on July 18, 2024

Looks like the SolarEdge UI … If so, I might have some template sensors and automations that’ll help with that.

from emhass.

altonius avatar altonius commented on July 18, 2024

Looks like the SolarEdge UI … If so, I might have some template sensors and automations that’ll help with that.

Cheers, I have a bunch already configured, and was trying to show a very simple view of the dc-coupled setup.  I'm always happy to learn how people have setup sensors and automations.

from emhass.

Deztak avatar Deztak commented on July 18, 2024

The (custom) sensors are in a file so that I don't have to restart each time I make a change, as you do with changes to the config.yaml file: (note: the "sensor.power_production_###" sensors are from the two forecast.solar integrations I'm running as I have two arrays facing very different directions) I'm very much an amateur coder, sorry if it's difficult to follow what I am doing with it.

platform: template
sensors:
    consumption_power_w:
        unique_id: "sensor.consumption_power_w"
        friendly_name: "Consumption Power W"
        device_class: "power"
        unit_of_measurement: "W"
        value_template: >
            {{ float(states('sensor.solaredge_i1_ac_power')) - float(states('sensor.solaredge_m1_ac_power')) }}
    solar_power_w:
        unique_id: "sensor.solar_power_w"
        friendly_name: "Solar Power W"
        device_class: "power"
        unit_of_measurement: "W"
        value_template: >
            {% set blah = namespace (
                batt = float(states('sensor.battery_power_w')),
                inv = float(states('sensor.solaredge_i1_ac_power')),
                solar = 0
                ) %}
            {% if states('sun.sun') == 'above_horizon' %}
                {% if blah.inv >= float(0) %}
                    {% if blah.batt >= float(0) %}
                        {% set blah.solar = (blah.inv + blah.batt) %}
                    {% else %}
                        {% set blah.solar = (blah.inv - blah.batt) %}
                    {% endif %}
                {% else %}
                    {% set blah.solar = (blah.inv + blah.batt) %}
                {% endif %}
            {% else %}
            {   % set blah.solar = float(0) %}
            {% endif %}
            {% if blah.solar < 0 %}
                {% set blah.solar = float(0) %}
            {% endif %}
            {{ blah.solar }}
    battery_charge_limit:
        unique_id: "sensor.battery_charge_limit"
        friendly_name: "Battery Charge Limit"
        unit_of_measurement: "W"
        value_template: >
                {{ min( 11400,
                    13000 +
                    min( states('sensor.power_production_now')|float(0) + states('sensor.power_production_now_2')|float(0),
                        states('sensor.power_production_next_hour')|float(0) + states('sensor.power_production_next_hour_2')|float(0),
                        float(states('sensor.solar_power_w')) ) / 1.2 -
                        max( float(states('sensor.consumption_power_w')),
                            float(states('sensor.p_load_forecast'))
                            ) * 1.2
                        )|round(0)|int(0) }}

yaml to implement from the automations editor:

alias: Battery Limits refresh
description: ""
trigger:
  - platform: time_pattern
    seconds: /30
condition:
  - condition: state
    entity_id: automation.emhass_publish_data_2
    attribute: current
    state: "off"
action:
  - if:
      - condition: or
        conditions:
          - condition: state
            entity_id: sensor.solaredge_i1_ac_power
            state: unavailable
          - condition: state
            entity_id: sensor.solaredge_i1_ac_power
            state: unknown
    then:
      - service: homeassistant.reload_all
        metadata: {}
        data: {}
      - delay:
          hours: 0
          minutes: 0
          seconds: 30
          milliseconds: 0
  - choose:
      - conditions:
          - condition: state
            entity_id: select.solaredge_i1_storage_command_mode
            state: Maximize Self Consumption
        sequence:
          - service: script.battery_reset
            metadata: {}
            data: {}
      - conditions:
          - condition: state
            entity_id: select.solaredge_i1_storage_command_mode
            state: Discharge to Maximize Export
        sequence:
          - service: script.battery_set_discharge_to_maximize_export
            data: {}
      - conditions:
          - condition: or
            conditions:
              - condition: state
                entity_id: select.solaredge_i1_storage_command_mode
                state: Charge from Solar Power and Grid
              - condition: state
                entity_id: select.solaredge_i1_storage_command_mode
                state: Charge from Solar Power
        sequence:
          - service: script.battery_set_charge_from_solar_power_and_grid
            metadata: {}
            data: {}
mode: single

This is the script that changes the battery setting ... note, if there is more solar the batteries can consume then I go to 'Charge from Solar Only' mode

alias: Battery - Charge from Solar Power and Grid
sequence:
  - if:
      - condition: or
        conditions:
          - condition: numeric_state
            entity_id: sensor.solar_power_w
            above: sensor.battery_charge_limit
    then:
      - if:
          - condition: not
            conditions:
              - condition: state
                entity_id: select.solaredge_i1_storage_command_mode
                state: Charge from Solar Power
        then:
          - service: select.select_option
            data:
              option: Charge from Solar Power
            target:
              entity_id: select.solaredge_i1_storage_command_mode
      - if:
          - condition: numeric_state
            entity_id: number.solaredge_i1_storage_charge_limit
            below: 11400
        then:
          - service: number.set_value
            data:
              value: "11400"
            target:
              entity_id: number.solaredge_i1_storage_charge_limit
    else:
      - if:
          - condition: numeric_state
            entity_id: sensor.battery_charge_limit
            below: 11400
        then:
          - service: number.set_value
            data:
              value: "{{int(states('sensor.battery_charge_limit'))}}"
            target:
              entity_id: number.solaredge_i1_storage_charge_limit
        else:
          - service: number.set_value
            data:
              value: "11400"
            target:
              entity_id: number.solaredge_i1_storage_charge_limit
      - if:
          - condition: not
            conditions:
              - condition: state
                entity_id: select.solaredge_i1_storage_command_mode
                state: Charge from Solar Power and Grid
        then:
          - service: select.select_option
            data:
              option: Charge from Solar Power and Grid
            target:
              entity_id: select.solaredge_i1_storage_command_mode
  - if:
      - condition: and
        conditions:
          - condition: numeric_state
            entity_id: number.solaredge_i1_site_limit
            below: 10000
    then:
      - service: number.set_value
        data:
          value: "10000"
        target:
          entity_id:
            - number.solaredge_i1_site_limit
  - if:
      - condition: numeric_state
        entity_id: number.solaredge_i1_storage_discharge_limit
        below: 11400
    then:
      - service: number.set_value
        data:
          value: "11400"
        target:
          entity_id: number.solaredge_i1_storage_discharge_limit
mode: single

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024

I'm struggling to figure out where to put "inverter_is_hybrid = False" and I can't see anything in the docs/readme/configUI for v0.9.1

So not yet published/released nor documented, just a dev base code for now. I set that option manually in the said script.

from emhass.

Deztak avatar Deztak commented on July 18, 2024

Let me have a go at testing. I'm going to try running this locally (instead of trying to update the EMHASS add-on) and how I go back on a command line.

Sorry I didn't gave much further explanation. This is not released on any add-on version, so you will only find the base code on a development git branch. There is a script that you can use on that branch. In a machine with Python installed the steps are: clone the repo, set an environment, switch to dev branch, launch the script...

git clone https://github.com/davidusb-geek/emhass.git
cd emhass
python -m venv .venv
source .venv/bin/activate
python setup.py install
git checkout davidusb-geek/dev/hybrid_inverter_def_seq
python scripts/script_debug_optim.py

Parlez vous Anglais?

from emhass.

altonius avatar altonius commented on July 18, 2024

yay, the above has got me running the script in WSL, rather than in an add-on. What's the best way to plug in my own data? do I need to configure the config file(s) to point to my HA and configure my battery / pv setup? or can I just run the script with data like I do to the API endpoint?

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024

yay, the above has got me running the script in WSL, rather than in an add-on. What's the best way to plug in my own data? do I need to configure the config file(s) to point to my HA and configure my battery / pv setup? or can I just run the script with data like I do to the API endpoint?

Great!

The best way that I can think is to pass the data as lists directly.
So you need to replace the whole first part of the script, from line 33 to line 70, with something like this (I haven't tested this):

with open(emhass_conf['config_path'], 'r') as file:
    params = yaml.load(file, Loader=yaml.FullLoader)
params.update({
    'params_secrets': {
        'hass_url': 'http://supervisor/core/api',
        'long_lived_token': '${SUPERVISOR_TOKEN}',
        'time_zone': 'Europe/Paris',
        'lat': 45.83,
        'lon': 6.86,
        'alt': 4807.8
    }
    })
runtimeparams = {
    'pv_power_forecast':[i+1 for i in range(48)],
    'load_power_forecast':[i+1 for i in range(48)],
    'load_cost_forecast':[i+1 for i in range(48)],
    'prod_price_forecast':[i+1 for i in range(48)]
}
runtimeparams_json = json.dumps(runtimeparams)
params['passed_data'] = runtimeparams
params_json = json.dumps(params)
retrieve_hass_conf, optim_conf, plant_conf = utils.get_yaml_parse(
    emhass_conf, use_secrets=False, params=params_json)
set_type = "dayahead-optim"
params, retrieve_hass_conf, optim_conf, plant_conf = utils.treat_runtimeparams(
    runtimeparams_json, params_json, retrieve_hass_conf, 
    optim_conf, plant_conf, set_type, logger)
rh = RetrieveHass(
    retrieve_hass_conf['hass_url'], retrieve_hass_conf['long_lived_token'], 
    retrieve_hass_conf['freq'], retrieve_hass_conf['time_zone'],
    params, emhass_conf, logger)
if self.get_data_from_file:
    with open((emhass_conf['data_path'] / 'test_df_final.pkl'), 'rb') as inp:
        rh.df_final, days_list, var_list = pickle.load(inp)
    retrieve_hass_conf['var_load'] = str(self.var_list[0])
    retrieve_hass_conf['var_PV'] = str(self.var_list[1])
    retrieve_hass_conf['var_interp'] = [retrieve_hass_conf['var_PV'], retrieve_hass_conf['var_load']]
    retrieve_hass_conf['var_replace_zero'] = [retrieve_hass_conf['var_PV']]
else:
    days_list = utils.get_days_list(retrieve_hass_conf['days_to_retrieve'])
    var_list = [retrieve_hass_conf['var_load'], retrieve_hass_conf['var_PV']]
    rh.get_data(days_list, var_list, minimal_response=False, significant_changes_only=False)
rh.prepare_data(
    retrieve_hass_conf['var_load'], load_negative = retrieve_hass_conf['load_negative'],
    set_zero_min = retrieve_hass_conf['set_zero_min'], 
    var_replace_zero = retrieve_hass_conf['var_replace_zero'], 
    var_interp = retrieve_hass_conf['var_interp'])
df_input_data = rh.df_final.copy()
fcst = Forecast(
    retrieve_hass_conf, optim_conf, plant_conf, 
    params_json, emhass_conf, logger, get_data_from_file=True)

P_PV_forecast = fcst.get_weather_forecast(method='list')
df_input_data.index = P_PV_forecast.index
df_input_data.index.freq = rh.df_final.index.freq
P_load_forecast = fcst.get_load_forecast(method='list')
df_input_data = pd.concat([P_PV_forecast, P_load_forecast], axis=1)
df_input_data.columns = ['P_PV_forecast', 'P_load_forecast']

df_input_data = fcst.get_load_cost_forecast(df_input_data, method='list')
df_input_data = fcst.get_prod_price_forecast(df_input_data, method='list')

So in the dictionary runtimeparams you can manually place your own data.
For example:

runtimeparams = {
    'pv_power_forecast':[1, 2, 3, 4, 5, 6, 7, 8, 9],
    'load_power_forecast':[1, 2, 3, 4, 5, 6, 7, 8, 9],
    'load_cost_forecast':[1, 2, 3, 4, 5, 6, 7, 8, 9],
    'prod_price_forecast':[1, 2, 3, 4, 5, 6, 7, 8, 9]
}

from emhass.

Deztak avatar Deztak commented on July 18, 2024

I feel like I may need to use the pip command to allow me to import a GitHub module that is commonly shortened to “git” in a similar way to how pandas is commonly “import pandas as pd” … when I have time I might hit stack overflow to try and fill in the gaps.

from emhass.

altonius avatar altonius commented on July 18, 2024

i've been able to start modifying the file, had to add a couple of imports + remove a few self. references but that's about as far as I can get. I've uploaded where I got upto here, it has a days worth of data that i'm attempting to play with

from emhass.

davidusb-geek avatar davidusb-geek commented on July 18, 2024

Ok this is included in the just released new version.
Closing this for now but reopen if eneded.

from emhass.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.