REST API command/platform fails on POST to external URL (solcast)

So I haven’t migrated my stuff over to a split, 2 Solcast-site setup yet, and I was still posting PV tuning data.

I did notice this morning that I seem to be getting HTTP 400 errors on the posted data, and also while it still shows PV Tuning params on Solcast’s dashboards, my accuracy data seems to have no data points the last day or so.

I’m guessing this is it and that they’ve stopped the tuning now?

Got this from them: “Tuned” Rooftop Sites After PV Tuning Discontinued | Solcast - Help Center

Not going to shout too loudly, but mine is still working. It currently shows “Last measurement: 37 mins ago” and the graph looks normal!

Strange as that link says its turned off for all!

Just setting up solcast with hassio through the pluggin. Curious how are people practically using this information for any automations?

For example i was thinking if my actuals deviated by > x% from the estimate it could alert me to a potential problem in the system…

My main use is just to graph predicted vs actual to keep an eye on deviations.

1 Like

I use the following day forecast to decide wheter to charge the battery during the night or not

1 Like

Hi Guys!

Thanks for the component @dannerph !
I’m receiving steady history and forecast values.

However i only manage to see the total kWh forecast for tomorrow/day after
image

Is it possible to access the 30 min forecast provided by the API ?

0.1526,0.0198,0.3919,2021-04-19T05:30:00Z,PT30M
0.3169,0.0395,0.9948,2021-04-19T06:00:00Z,PT30M
0.6305,0.0631,1.6194,2021-04-19T06:30:00Z,PT30M
0.9653,0.0873,2.2339,2021-04-19T07:00:00Z,PT30M
1.2698,0.1097,2.775,2021-04-19T07:30:00Z,PT30M

That would really be beneficial for my home power consumption optimization (for example switch on heat pump long term or rather use the heating coils)

Thanks a lot!

I’m pretty new to Home Assistant, just trying to get this set up to get some idea of solar prediction for next day.

I’ve installed this and configured it as far as I’m aware but I am getting this error in my log:

"Solcast entities not yet registered, try again next day"

I can see its hit the API as the count has increased, if I try the call manually using the URL they show on Solcast it returns me data.

Any ideas what to look at?

Nevermind, after a second reboot of HassOS it seems to be alive now. Now I just need to try and configure a second instance as I have two arrays, East and West facing and want a total.

Can anyone help me with the SolCast custom component please?

I’ve left it running for a few days and:
The 3 day forecast is received OK, however the forecast history runs when HA is restart, but than stops.
The API count does not reduce below 49.
Looking in the log, the only error I can see with Solcast mentioned is as below. As the component is calling for sunrise information I’ve checked, my sun.sun state and that appears to be working?

2021-05-09 05:18:54 ERROR (MainThread) [homeassistant] Error doing job: Exception in callback async_track_point_in_utc_time.<locals>.run_action(<Job HassJobT...e98a33a4c0>)>>) at /usr/src/homeassistant/homeassistant/helpers/event.py:1176
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/asyncio/events.py", line 81, in _run
    self._context.run(self._callback, *self._args)
  File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 1195, in run_action
    hass.async_run_hass_job(job, utc_point_in_time)
  File "/usr/src/homeassistant/homeassistant/core.py", line 424, in async_run_hass_job
    hassjob.target(*args)
  File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 1317, in _handle_sun_event
    self.hass.async_run_hass_job(self.job)
  File "/usr/src/homeassistant/homeassistant/core.py", line 424, in async_run_hass_job
    hassjob.target(*args)
  File "/config/custom_components/solcast/__init__.py", line 237, in sunrise_call_action
    next_setting = get_location_astral_event_next(
  File "/usr/src/homeassistant/homeassistant/helpers/sun.py", line 84, in get_location_astral_event_next
    getattr(location, event)(
TypeError: getattr(): attribute name must be string

I’ve been having a play, the scripts work OK if I call them manually, it is just the auto refresh that doesn’t work.

I believe my config is correct:

solcast:
  api_key: redacted
  resource_id: redacted
  api_limit: 50
  disable_ssl_check: False
  disable_automatic_forecast_fetching: False
  disable_automatic_history_fetching: False

OK, so a little more digging and diagnostics, I found this blog article: Blog | Home Assistant Developer Docs

The April 21st entry mentions " The sun helper has changed its signature for get_astral_location and get_location_astral_event_next to include an elevation parameter. Also the return value of get_astral_location has changed to a tuple including elevation."

So I assume this is the reason I receive the error:

TypeError: getattr(): attribute name must be string

I’ve tried to look at the code, but it is a bit beyond my skill set to track through how it works.

As an aside there the first article in the blog is: “Replacing pytz with python-dateutil” which will happen in the 2021.6 release, so I guess that may also break something?

Is anyone else having an issue with the Solcast Component on 2021.5?

Thank you

Hi,
HA 2021.6 solcast component not work. The API counter changes but I have errors in HA and unknow values on the sensors.
1

Maybe my alternative approach suits you too… At the moment I’m happy with the forecast values only, and therefore I configured them directly as sensors in configuration.yaml.

The api call is executed once an hour for all sensors together. Because the current limit of Socast is 50 calls within 24 hours, this fits. It could probably also be executed manually via the service ‘homeassistant.update_entity’.

One point that is not yet properly solved is the alignment between UTC and the local time zone. However, since I live very close to UTC, it does not matter for me at the moment.

Suggestions for improvements and extensions are welcome.

Here you go:

sensor:
  - platform: rest
    name: solcast_forecast_data
    json_attributes:
      - forecasts
    resource: https://api.solcast.com.au/rooftop_sites/SOLCAST_RESOURCE_ID/forecasts?format=json&api_key=SOLCAST_API_KEY
    method: GET
    value_template: "OK"
    scan_interval: 01:00
    force_update: true
  - platform: template
    sensors:
        solcast_forecast_average_30min:
            value_template: "{{ state_attr('sensor.solcast_forecast_data', 'forecasts')[0].pv_estimate|default('variable is not defined')|round(2) }}"
            unit_of_measurement: 'kW'
        solcast_forecast_average_60min:
            value_template: >-
              {{ ((state_attr('sensor.solcast_forecast_data', 'forecasts')[0].pv_estimate|default('variable is not defined') + state_attr('sensor.solcast_forecast_data', 'forecasts')[1].pv_estimate|default('variable is not defined'))/2)|round(2) }}
            unit_of_measurement: 'kW'
        solcast_forecast_today:
            value_template: >-
              {% set ns = namespace (fc_today = 0) %}
              {% for forecast in state_attr('sensor.solcast_forecast_data', 'forecasts')|default('variable is not defined') %}
                {% set daydiff = as_local(strptime(forecast.period_end, '%Y-%m-%dT%H:%M:%S.%f0Z')).date() - as_local(utcnow()).date() %} 
                {% if daydiff.days == 0 %}
                  {% set ns.fc_today = ns.fc_today + (forecast.pv_estimate/2)|float %}
                {%- endif %}
              {%- endfor %}
              {{ ns.fc_today|round(2) }}
            unit_of_measurement: 'kWh'
        solcast_forecast_tommorrow:
            value_template: >-
              {% set ns = namespace (fc_tommorrow = 0) %}
              {% for forecast in state_attr('sensor.solcast_forecast_data', 'forecasts')|default('variable is not defined') %}
                {% set daydiff = as_local(strptime(forecast.period_end, '%Y-%m-%dT%H:%M:%S.%f0Z')).date() - as_local(utcnow()).date() %} 
                {% if daydiff.days == 1 %}
                  {% set ns.fc_tommorrow = ns.fc_tommorrow + (forecast.pv_estimate/2)|float %}
                {%- endif %}
              {%- endfor %}
              {{ ns.fc_tommorrow|round(2) }}
            unit_of_measurement: 'kWh'
        solcast_forecast_day_after_tommorrow:
            value_template: >-
              {% set ns = namespace (fc_dayAftTom = 0) %}
              {% for forecast in state_attr('sensor.solcast_forecast_data', 'forecasts')|default('variable is not defined') %}
                {% set daydiff = as_local(strptime(forecast.period_end, '%Y-%m-%dT%H:%M:%S.%f0Z')).date() - as_local(utcnow()).date() %} 
                {% if daydiff.days == 2 %}
                  {% set ns.fc_dayAftTom = ns.fc_dayAftTom + (forecast.pv_estimate/2)|float %}
                {%- endif %}
              {%- endfor %}
              {{ ns.fc_dayAftTom|round(2) }}
            unit_of_measurement: 'kWh'
4 Likes

Many thanks, I try

@climb Thanks for sharing your code. It works really well and is easy to expand for writing automations. I was wondering if the data_generator option from the apexcharts-card could be used to plot the forecasts in future. The example mentions exactly this kind of function. Unfortunately my coding skills are not good enough to get it to work.

https://github.com/RomRider/apexcharts-card#data_generator-option

This may be of interest to people in this topic, as of 107 a new integration to Forecast.Solar has been added: Forecast.Solar - Home Assistant

Thanks for the hint. Maybe I give it a try.

A little update from my side:

  • The timezone problem should be fixed now.
  • There are two new sensors for the value and time of the maximum expected amount from today.
sensor:
  - platform: rest
    name: solcast_forecast_data
    json_attributes:
      - forecasts
    resource: https://api.solcast.com.au/rooftop_sites/SOLCAST_RESOURCE_ID/forecasts?format=json&api_key=SOLCAST_API_KEY
    method: GET
    value_template: "OK"
    scan_interval: 01:00
    force_update: true
  - platform: template
    sensors:
        solcast_forecast_average_30min:
            value_template: "{{ state_attr('sensor.solcast_forecast_data', 'forecasts')[0].pv_estimate|default('variable is not defined')|round(2) }}"
            unit_of_measurement: 'kW'
        solcast_forecast_average_60min:
            value_template: >-
              {{ ((state_attr('sensor.solcast_forecast_data', 'forecasts')[0].pv_estimate|default('variable is not defined') + state_attr('sensor.solcast_forecast_data', 'forecasts')[1].pv_estimate|default('variable is not defined'))/2)|round(2) }}
            unit_of_measurement: 'kW'
        solcast_forecast_today:
            value_template: >-
              {% set ns = namespace (fc_today = 0) %}
              {% for forecast in state_attr('sensor.solcast_forecast_data', 'forecasts')|default('variable is not defined') %}
                {% set daydiff = as_local(strptime(forecast.period_end, '%Y-%m-%dT%H:%M:%S.%f0Z').replace(tzinfo=utcnow().tzinfo)).date() - as_local(utcnow()).date() %} 
                {% if daydiff.days == 0 %}
                  {% set ns.fc_today = ns.fc_today + (forecast.pv_estimate/2)|float %}
                {%- endif %}
              {%- endfor %}
              {{ ns.fc_today|round(2) }}
            unit_of_measurement: 'kWh'
        solcast_forecast_today_max:
            value_template: >-
              {% set ns = namespace (fc_today_max = 0) %}
              {% for forecast in state_attr('sensor.solcast_forecast_data', 'forecasts')|default('variable is not defined') %}
                {% set daydiff = as_local(strptime(forecast.period_end, '%Y-%m-%dT%H:%M:%S.%f0Z').replace(tzinfo=utcnow().tzinfo)).date() - as_local(utcnow()).date() %} 
                {% if daydiff.days == 0 %}
                  {% if ns.fc_today_max < forecast.pv_estimate|float %}
                    {% set ns.fc_today_max = forecast.pv_estimate|float %}
                  {%- endif %}
                {%- endif %}
              {%- endfor %}
              {{ ns.fc_today_max|round(2) }}
            unit_of_measurement: 'kW'
        solcast_forecast_today_max_time:
            value_template: >-
              {% set ns = namespace (fc_today_max = 0, fc_today_max_time = 0) %}
              {% for forecast in state_attr('sensor.solcast_forecast_data', 'forecasts')|default('variable is not defined') %}
                {% set daydiff = as_local(strptime(forecast.period_end, '%Y-%m-%dT%H:%M:%S.%f0Z').replace(tzinfo=utcnow().tzinfo)).date() - as_local(utcnow()).date() %} 
                {% if daydiff.days == 0 %}
                  {% if ns.fc_today_max < forecast.pv_estimate|float %}
                    {% set ns.fc_today_max = forecast.pv_estimate|float %}
                    {% set ns.fc_today_max_time = as_local(strptime(forecast.period_end, '%Y-%m-%dT%H:%M:%S.%f0Z').replace(tzinfo=utcnow().tzinfo)).time() %}
                  {%- endif %}
                {%- endif %}
              {%- endfor %}
              {{ ns.fc_today_max_time }}
        solcast_forecast_tommorrow:
            value_template: >-
              {% set ns = namespace (fc_tommorrow = 0) %}
              {% for forecast in state_attr('sensor.solcast_forecast_data', 'forecasts')|default('variable is not defined') %}
                {% set daydiff = as_local(strptime(forecast.period_end, '%Y-%m-%dT%H:%M:%S.%f0Z').replace(tzinfo=utcnow().tzinfo)).date() - as_local(utcnow()).date() %} 
                {% if daydiff.days == 1 %}
                  {% set ns.fc_tommorrow = ns.fc_tommorrow + (forecast.pv_estimate/2)|float %}
                {%- endif %}
              {%- endfor %}
              {{ ns.fc_tommorrow|round(2) }}
            unit_of_measurement: 'kWh'
        solcast_forecast_day_after_tommorrow:
            value_template: >-
              {% set ns = namespace (fc_dayAftTom = 0) %}
              {% for forecast in state_attr('sensor.solcast_forecast_data', 'forecasts')|default('variable is not defined') %}
                {% set daydiff = as_local(strptime(forecast.period_end, '%Y-%m-%dT%H:%M:%S.%f0Z').replace(tzinfo=utcnow().tzinfo)).date() - as_local(utcnow()).date() %} 
                {% if daydiff.days == 2 %}
                  {% set ns.fc_dayAftTom = ns.fc_dayAftTom + (forecast.pv_estimate/2)|float %}
                {%- endif %}
              {%- endfor %}
              {{ ns.fc_dayAftTom|round(2) }}
            unit_of_measurement: 'kWh'
2 Likes

@james_hiscott You’re welcome. My main goal is automation, so the actual figures are enough for me. Maybe you will find more help in this mentioned topic.

Hi @climb - thank you so much for doing this work and making it available. It solves a big problem for me because my my time zone has the solar production period cut up by the UTC day change.

It also looks like this could be good for me to use for my split system. I think I can duplicate and edit the code to work, but wanted to check that the items I’d need to change in the duplicated code are:

  • the solcast_forecast_data (e.g. solecast_forecast_data_2) in its definition and when called in the code
  • the SOLCAST_RESOURCE_ID
  • the name of each of the sensors (e.g. solcast_forecast_average_30min becomes solcast_forecast_average_30min_2)

Is that it? Or do I also need to change some of what look like internal working variables like forecast, forecast.pv_estimate, ns.fc_today etc.

Thanks again

Thanks for your great feedback. You’re welcome!

And yes, that should it be.

  • The internal variables don’t affect the other sensors.
  • You have to call the API and configure the sensors for each site (SOLCAST_RESOURCE_ID) separately.
  • This is one of the three proposed solutions in this post of Solcast.