davidusb-geek / emhass

emhass: Energy Management for Home Assistant, is a Python module designed to optimize your home energy interfacing with Home Assistant.
MIT License
301 stars 61 forks source link

Solcast 2 rooftop ids #21

Closed gieljnssns closed 2 years ago

gieljnssns commented 2 years ago

I have 2 solcast rooftop ids, how can i pass that data? I'm also using https://github.com/oziee/ha-solcast-solar, so I have solcast sensors in my HA, is it possible to pass that data?

davidusb-geek commented 2 years ago

Hi, you will need to fuze the two sensors on a single one using templates. Then feed that single sensor data passing the data as a list when calling the shell command, just as described in the documentation here: https://emhass.readthedocs.io/en/latest/forecasts.html#passing-your-own-forecast-data

davidusb-geek commented 2 years ago

Hi, did you find a solution for this?

gieljnssns commented 2 years ago

Now I use for my rest sensors

- platform: rest
  name: "Solcast Forecast huis"
  json_attributes:
    - forecasts
  resource: https://api.solcast.com.au/rooftop_sites/xxxxxxxxxxc/forecasts?format=json&api_key=xxxxxxxxx&hours=24
  method: GET
  value_template: "{{ (value_json.forecasts[0].pv_estimate)|round(2) }}"
  unit_of_measurement: "kW"
  device_class: power
  scan_interval: 86400
  force_update: true

- platform: rest
  name: "Solcast Forecast garage"
  json_attributes:
    - forecasts
  resource: https://api.solcast.com.au/rooftop_sites/xxxxxxxxxxc/forecasts?format=json&api_key=xxxxxxxxx&hours=24
  method: GET
  value_template: "{{ (value_json.forecasts[0].pv_estimate)|round(2) }}"
  unit_of_measurement: "kW"
  device_class: power
  scan_interval: 86400
  force_update: true

Then i use 2 templates

    solcast_24hrs_forecast_garage:
      value_template: >-
        {%- set awattar_all_list = state_attr('sensor.solcast_forecast_garage', 'forecasts') | map(attribute='pv_estimate') | list %}
        {%- set values_all = namespace(all=[]) %}
        {% for i in range(awattar_all_list | length) %}
          {%- set v = (awattar_all_list[i] | float |multiply(1000) ) | int(0) %}
          {%- set values_all.all = values_all.all + [ v ] %}
        {%- endfor %} {{ (values_all.all)[:48] }}

    solcast_24hrs_forecast_huis:
      value_template: >-
        {%- set awattar_all_list = state_attr('sensor.solcast_forecast_huis', 'forecasts') | map(attribute='pv_estimate') | list %}
        {%- set values_all = namespace(all=[]) %}
        {% for i in range(awattar_all_list | length) %}
          {%- set v = (awattar_all_list[i] | float |multiply(1000) ) | int(0) %}
          {%- set values_all.all = values_all.all + [ v ] %}
        {%- endfor %} {{ (values_all.all)[:48] }}

And another to combine those 2

    solcast_24hrs_forecast:
      value_template: >-
        {% set a = states("sensor.solcast_24hrs_forecast_garage")[1:-1].split(',') | map('int') | list %}
        {% set b = states("sensor.solcast_24hrs_forecast_huis")[1:-1].split(',') | map('int') | list %}
        {% set ns = namespace(items = []) %}
        {% for i in range(a | length) %}
          {% set ns.items = ns.items + [ a[i]  + b[i]  ] %}
        {% endfor %}
        {{ ns.items }}

I have 2 shell commands

publish_data: "curl -i -H 'Content-Type:application/json' -X POST -d '{}' http://localhost:5001/action/publish-data"
dayahead_optim: curl -i -H 'Content-Type:application/json' -X POST -d '{"pv_power_forecast":{{states('sensor.solcast_24hrs_forecast')}}}' http://localhost:5001/action/dayahead-optim

Then I use this automation

alias: EMHASS data
id: 684e7c96-7eb8-41fa-b81c-e3c97e234b56
trigger:
  - platform: time
    at: "05:30:00"
    id: "dayahead"
  - platform: time_pattern
    minutes: /5
action:
  - choose:
      - conditions:
          - condition: trigger
            id: "dayahead"
        sequence:
          - service: homeassistant.update_entity
            data: {}
            target:
              entity_id:
                - sensor.solcast_forecast_garage
                - sensor.solcast_forecast_huis
          - delay:
              minutes: 1
          - service: shell_command.dayahead_optim
    default:
      - service: shell_command.publish_data

Do I have to leave method: solcast in my configuration?

davidusb-geek commented 2 years ago

Great, thanks for sharing. Would you mind if I put some of this in the documentation? To help other people with the same use case? No need to change the method, it will be automatically changed to list when passing a list at runtime

purcell-lab commented 2 years ago

I have two arrays east and west facing and provide this solution like this:

image

- platform: rest
  name: "Solcast Forecast West"
  json_attributes:
    - forecasts
  resource: https://api.solcast.com.au/rooftop_sites/4db1-7ec8-f883-c123/forecasts?format=json&api_key=XXXX&hours=48
  method: GET
  value_template: "{{ (value_json.forecasts[0].pv_estimate)|round(2) }}"
  unit_of_measurement: "kW"
  device_class: power
  scan_interval: 06:00:00
  force_update: true

- platform: rest
  name: "Solcast Forecast East"
  json_attributes:
    - forecasts
  resource: https://api.solcast.com.au/rooftop_sites/60b4-41b9-80ca-06b0/forecasts?format=json&api_key=XXXX&hours=48
  method: GET
  value_template: "{{ (value_json.forecasts[0].pv_estimate)|round(2) }}"
  unit_of_measurement: "kW"
  device_class: power
  scan_interval: 06:00:00
  force_update: true
    - name: solcast 24hrs forecast 
      state: >-
          {%- set solcast_west_list = state_attr('sensor.solcast_forecast_west', 'forecasts')|selectattr('period_end','gt',utcnow().isoformat())|map(attribute='pv_estimate')|list %}
          {%- set solcast_east_list = state_attr('sensor.solcast_forecast_east', 'forecasts')|selectattr('period_end','gt',utcnow().isoformat())|map(attribute='pv_estimate')|list %}

          {%- set values_all = namespace(all=[]) %}
          {% for i in range(solcast_west_list | length) %}
           {%- set v = ((solcast_west_list[i] + solcast_east_list[i]) | float |multiply(1000) ) | int(0) %}
            {%- set values_all.all = values_all.all + [ v ] %}
          {%- endfor %} {{ ([states('sensor.APF_Generation_Entity')|int(0)] + (values_all.all)[1:48]) }}
  post_mpc_optim: "curl -i -H \"Content-Type: application/json\" -X POST -d '{\"load_cost_forecast\":{{(
          ([states('sensor.amber_general_price')|float(0)] +
          state_attr('sensor.amber_general_forecast', 'forecasts') |map(attribute='per_kwh')|list)[:48])
          }}, \"prod_price_forecast\":{{(
          ([states('sensor.amber_feed_in_price')|float(0)] +
          state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list)[:48]) 
          }}, \"pv_power_forecast\":{{states('sensor.solcast_24hrs_forecast')
          }}, \"prediction_horizon\":{{min(48,
          (state_attr('sensor.amber_feed_in_forecast', 'forecasts')|map(attribute='per_kwh')|list|length)+1)
          }},\"alpha\":0, \"beta\":1, \"soc_init\":{{(states('sensor.powerwall_charge')|float(0))/100
          }}, \"soc_final\":0.05, \"def_total_hours\":[{{states('sensor.def_total_hours_pool_filter')
          }},{{states('sensor.def_total_hours_pool_heatpump')
          }},{{states('sensor.def_total_hours_ev')
          }},{{states('sensor.def_total_hours_hvac')
          }},{{states('sensor.def_total_hours_hws')
          }}]}' http://localhost:5000/action/naive-mpc-optim"
gieljnssns commented 2 years ago

@davidusb-geek You can use all my config

davidusb-geek commented 2 years ago

Thanks! I just added a complete new example to fusion two sensors to the documentation.