Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Increased configuration parameters to match with increased support in options.json #69

Merged
merged 9 commits into from
Jan 28, 2024

Conversation

GeoDerp
Copy link
Contributor

@GeoDerp GeoDerp commented Jan 23, 2024

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Jan 24, 2024

The thought was that items (such as solcast_api_key) commonly used in curl post commands could be redacted from this poll request.

The reasoning for adding all parameters into the configuration page was to assist in new EMHASS users.
All parameters in one location may help users to understand what parameters could be changed, while placing them all in a central location. This also results in an minimal integration of the automations.yaml & configuration.yaml. The thought is that most people could use the base examples:

In configuration.yaml:

shell_command:
dayahead_optim: "curl -i -H "Content-Type:application/json" -X POST -d '{}' http://localhost:5000/action/dayahead-optim"
publish_data: "curl -i -H "Content-Type:application/json" -X POST -d '{}' http://localhost:5000/action/publish-data"

In automations.yaml:

  • alias: EMHASS day-ahead optimization
    trigger:
    platform: time
    at: '05:30:00'
    action:
    • service: shell_command.dayahead_optim
  • alias: EMHASS publish data
    trigger:
    • minutes: /5
      platform: time_pattern
      action:
    • service: shell_command.publish_data

In most cases to develop a functioning EMHASS setup.
Some examples of automating (with bash commands & the terminal addon for example) could be documented later for an copy and past commands of adding the additions into there current setup.

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Jan 24, 2024

The downside to this method is that it will increase the configuration page bloat #48. Im hopping to see or request some way for home assistant configuration pages to support dropdowns or sections to make the parameters easier for the viewer

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Jan 24, 2024

Update: ill found the method of hiding optional parameters. Will look into adding later

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Jan 25, 2024

Commit 63f2483 currently does not work. I believe it may be from the optional parameters feeding empty values into EMHASS, overriding the the param values provided in config_emhass.yaml

…aml added default values and param names into desc and name. config_emhass copied formatting of EMHASS pull request 149
@GeoDerp
Copy link
Contributor Author

GeoDerp commented Jan 26, 2024

@davidusb-geek , you would know better then me, my idea of fixing this could be something like

https://github.com/davidusb-geek/emhass/blob/b66065e4fec74a1d400c0835f812d8539565b2d6/src/emhass/web_server.py#L100-L164

to

def build_params(params, options, addon):
    if addon == 1:
        #create associations list
        # conf, key, options name, 'param in list name (for lists)' 
        associations = []    
        # variables in retrieve_hass_conf
        associations.append['retrieve_hass_conf', 'freq', 'optimization_time_step']
        associations.append['retrieve_hass_conf', 'days_to_retrieve', 'historic_days_to_retrieve']
        associations.append['retrieve_hass_conf', 'var_PV', 'sensor_power_photovoltaics']
        associations.append['retrieve_hass_conf', 'var_load', 'sensor_power_load_no_var_loads']
        associations.append['retrieve_hass_conf', 'load_negative', 'load_negative']
        associations.append['retrieve_hass_conf', 'set_zero_min', 'set_zero_min']
        associations.append['retrieve_hass_conf', 'var_replace_zero', 'sensor_power_photovoltaics']
        associations.append['retrieve_hass_conf', 'method_ts_round', 'method_ts_round']
        associations.append['retrieve_hass_conf', 'solcast_api_key', 'optional_solcast_api_key']
        associations.append['retrieve_hass_conf', 'solcast_rooftop_id', 'optional_solcast_rooftop_id']
        associations.append['retrieve_hass_conf', 'solar_forecast_kwp', 'optional_solar_forecast_kwp']
        associations.append['retrieve_hass_conf', 'time_zone', 'time_zone']
        associations.append['retrieve_hass_conf', 'lat', 'Latitude']
        associations.append['retrieve_hass_conf', 'lon', 'Longitude']
        associations.append['retrieve_hass_conf', 'alt', 'Altitude']
        #  variables in optim_conf
        associations.append['optim_conf', 'set_use_battery', 'set_use_battery']
        associations.append['optim_conf', 'num_def_loads', 'number_of_deferrable_loads']
        associations.append['optim_conf', 'P_deferrable_nom', 'list_nominal_power_of_deferrable_loads', 'nominal_power_of_deferrable_loads']
        associations.append['optim_conf', 'def_total_hours', 'list_operating_hours_of_each_deferrable_load', 'operating_hours_of_each_deferrable_load']
        associations.append['optim_conf', 'treat_def_as_semi_cont', 'list_treat_deferrable_load_as_semi_cont', 'treat_deferrable_load_as_semi_cont']
        associations.append['optim_conf', 'set_def_constant', 'list_set_deferrable_load_single_constant', 'set_deferrable_load_single_constant']
        associations.append['optim_conf', 'weather_forecast_method', 'weather_forecast_method']
        associations.append['optim_conf', 'load_forecast_method', 'load_forecast_method']
        associations.append['optim_conf', 'delta_forecast', 'delta_forecast_daily']
        associations.append['optim_conf', 'load_cost_forecast_method', 'load_cost_forecast_method']
        associations.append['optim_conf', 'load_cost_hp', 'load_peak_hours_cost']
        associations.append['optim_conf', 'load_cost_hc', 'load_offpeak_hours_cost']
        associations.append['optim_conf', 'prod_price_forecast_method', 'production_price_forecast_method']
        associations.append['optim_conf', 'prod_sell_price', 'photovoltaic_production_sell_price']
        associations.append['optim_conf', 'set_total_pv_sell', 'set_total_pv_sell']
        associations.append['optim_conf', 'lp_solver', 'lp_solver']
        associations.append['optim_conf', 'lp_solver_path', 'lp_solver_path']
        associations.append['optim_conf', 'set_nocharge_from_grid', 'set_nocharge_from_grid']
        associations.append['optim_conf', 'set_nodischarge_to_grid', 'set_nodischarge_to_grid']
        associations.append['optim_conf', 'set_battery_dynamic', 'set_battery_dynamic']
        associations.append['optim_conf', 'battery_dynamic_max', 'battery_dynamic_max']
        associations.append['optim_conf', 'battery_dynamic_min', 'battery_dynamic_min']
        associations.append['optim_conf', 'weight_battery_discharge', 'weight_battery_discharge']
        associations.append['optim_conf', 'weight_battery_charge', 'weight_battery_charge']
        # variables in plant_conf
        associations.append['plant_conf', 'P_grid_max', 'maximum_power_from_grid']
        associations.append['plant_conf', 'module_model', 'list_pv_module_model', 'pv_module_model' ]
        associations.append['plant_conf', 'inverter_model', 'list_pv_inverter_model', 'pv_inverter_model' ]
        associations.append['plant_conf', 'surface_tilt', 'list_surface_tilt', 'surface_tilt' ]
        associations.append['plant_conf', 'surface_azimuth', 'list_surface_azimuth', 'surface_azimuth']
        associations.append['plant_conf', 'modules_per_string','list_modules_per_string', 'modules_per_string']
        associations.append['plant_conf', 'strings_per_inverter', 'list_strings_per_inverter', 'strings_per_inverter']
        associations.append['plant_conf', 'Pd_max', 'battery_discharge_power_max']
        associations.append['plant_conf', 'Pc_max', 'battery_charge_power_max']
        associations.append['plant_conf', 'eta_disch', 'battery_discharge_efficiency']
        associations.append['plant_conf', 'eta_ch', 'battery_charge_efficiency']
        associations.append['plant_conf', 'Enom', 'battery_nominal_energy_capacity']
        associations.append['plant_conf', 'SOCmin', 'battery_minimum_state_of_charge']
        associations.append['plant_conf', 'SOCmax', 'battery_maximum_state_of_charge']
        associations.append['plant_conf', 'SOCtarget', 'battery_target_state_of_charge']
        
        print(associations)

        for i in associations:
            # check if options are null 
            if  options[str(i[2])] is not None:
                #check if list
                if options[str(i[3])] is not None:
                    params[str(i[0])][str(i[1])] = [x[str(i[3])] for x in options[str(i[2])]]
                #check if dictionary
                elif type(options[str(i[2])]) is not dict:
                    params[str(i[0])][str(i[1])] = options[str(i[2])]
                else:    
                    params[str(i[0])][str(i[1])] = [options[str(i[2])]]

        ## add rest manually 
        params['retrieve_hass_conf']['var_interp'] = [options['sensor_power_photovoltaics'], options['sensor_power_load_no_var_loads']]
        start_hours_list = [i['peak_hours_periods_start_hours'] for i in options['list_peak_hours_periods_start_hours']]
        end_hours_list = [i['peak_hours_periods_end_hours'] for i in options['list_peak_hours_periods_end_hours']]
        num_peak_hours = len(start_hours_list)
        list_hp_periods_list = [{'period_hp_'+str(i+1):[{'start':start_hours_list[i]},{'end':end_hours_list[i]}]} for i in range(num_peak_hours)]
        params['optim_conf']['list_hp_periods'] = list_hp_periods_list

        print(params)

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Jan 26, 2024

GeoDerp/emhass@e616c36
It works, not sure if it completes what it set out to accomplish 😅. May want place a try loop before the null test.

@davidusb-geek
Copy link
Owner

>         # conf, key, options name, 'param in list name (for lists)' 
>         associations = []    
>         # variables in retrieve_hass_conf
>         associations.append['retrieve_hass_conf', 'freq', 'optimization_time_step']
>         associations.append['retrieve_hass_conf', 'days_to_retrieve', 'historic_days_to_retrieve']

Hi, this doesn't seems good. Did you test this?
That code will throw error:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: 'builtin_function_or_method' object is not subscriptable

Did you meant?:

associations = []    
associations.append(['retrieve_hass_conf', 'freq', 'optimization_time_step'])
associations.append(['retrieve_hass_conf', 'days_to_retrieve', 'historic_days_to_retrieve'])

...

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Jan 26, 2024

Sorry about that. I tested it via python and Docker. Seems like my testing still needs improvement.

Did you meant?:

associations = []    
associations.append(['retrieve_hass_conf', 'freq', 'optimization_time_step'])
associations.append(['retrieve_hass_conf', 'days_to_retrieve', 'historic_days_to_retrieve'])

...

I'm not surprised that I got a few things wrong. (It's currently 11am my time). Will change and test Tomorrow. 👍
Let me know if there are any tests besides the pytest and running the docker container you would recommend for verifying.

In hindsight most of my tests are prioritising testing configs.

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Jan 27, 2024

@davidusb-geek, whats the best method of testing options for the emhass-add-on? Is there a simple method of building emhass inside the Home Assistant addon devcontainer. have tried placing git+https://github.com/GeoDerp/emhass@testing inside the requirements.txt but no luck

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Jan 27, 2024

Another idea (besides idea: davidusb-geek/emhass@master...GeoDerp:emhass:testing ) I had was setting get methods with each option.

ex: (web_server/py)

 params['retrieve_hass_conf']['freq'] = options['optimization_time_step']

to

 params['retrieve_hass_conf']['freq'] = options.get('optimization_time_step', 30)

If it did work, would require setting defaults on all values.

Unfortunately i have hit an wall. I am unable to continue due to me lack of knowledge of how to properly locally build emhass to test emhass-add-on. Any help would be appreciated.

Thanks for putting up with me this far.

@davidusb-geek
Copy link
Owner

@GeoDerp let's try to come out with a new release that includes all your changes until now. Then if you have any more ideas you can open new PR's.

Yes sometime ago it was easy for me to test the add-on by using this procedure locally: https://developers.home-assistant.io/docs/add-ons/testing

This was very useful to test the add-on on a production-like environment.
However, several month ago this stopped working for me as the devcontainer always fail to start the test Home Assistant instance with errors.

So what I have done lately is to build the docker standalone image and locally running it to test the web server this way.

@@ -24,24 +24,15 @@ ingress: true
ingress_port: 5000
ingress_stream: true
options:
hass_url: empty
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you erased all these parameters to make them optional is that right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, its a weird way to do it. but thats how Home Assistant wants it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants