Converting Current Weather State to Number (for Solar Charger ON/OFF Automation)

I currently have some ESPHome relays that turn on/off some solar controllers based on whether the sun is above the horizon or below it.

I now want to create a better automation (that maybe requires creating a sensor or two?) that turns the relays on/off based on a numeric score ( as well as if the sun is above the horizon). I’m new to Home Assistant and definitely need help, especially with creating sensors/templates.

The step I’m stuck at currently is having Home Assistant check the current state of a weather API sensor (such as AccuWeather weather.home ) and then having it convert that state into a number --so that I can create an over-all number score for that weather sensor’s current state.

After accomplishing that, I’d also like to create a sensor that adds up an aggregate/total score of all of the individual weather APIs scores so that I can use an average of multiple weather APIs to make the determination.

Here’s what I’m looking to do …

For each weather API I would want to create a unique sensor, for example weather_score_accuweather could be the name and it would pull from weather.home Accuweather API sensor. Then weather_score_nws could be another, and so on.
If the current state is:
Unknown = 0
Rainy = 0
Cloudy = 0
Partly Cloudy = 1
Sunny = 2
Exceptional = 3

There are additional weather states that would need to have numbers assigned to them, but the ones listed above are most important to get started.

I have tried creating a Template Sensor and adding this to the “State template*” section but it doesn’t seem to work. The resulting value is always “0” and never changes (even when I temporarily assign unknown a -1 value for testing purposes).

{% set weather_state = states('weather.home') %}
{% if weather_state == 'Cloudy' %}
  0
{% elif weather_state == 'Partly cloudy' %}
  1
{% elif weather_state == 'Sunny' %}
  2
{% elif weather_state == 'Exceptional' %}
  3
{% else %}
  0
{% endif %}

I used the Helpers Gui to try this. There additional settings that I can enter such as “unit of measurement” but I’m not yet sure what I should enter.

After the individual weather score sensors are created and working, I think that I would need a final “all” sensor to pull the numbers from each individual weather_score sensor (for example, it could be called weather_score_all) to add up a final score.

From there I’d like to create (I’m guessing again) two automations to determine the on/off relay state by a time_pattern trigger : If “weather_score_all” sensor is above or below a certain amount, the relay switch will respond accordingly. It would go something like this (I think?) :

For the “ON” function:

alias: weather_score_relay_on_automation
description: ""
trigger:
  - platform: time_pattern
    minutes: /5
condition:
  - condition: numeric_state
    entity_id: sensor.weather_score_accuweather
    above: "0"
  - condition: state
    entity_id: sun.sun
    state: above_horizon
action:
  - type: turn_on
    device_id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    entity_id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    domain: switch
mode: single

For “OFF” function

description: ""
trigger:
  - platform: time_pattern
    minutes: /5
condition:
  - condition: numeric_state
    entity_id: sensor.weather_score_accuweather
    below: "1"
  - condition: state
    entity_id: sun.sun
    state: above_horizon
action:
  - type: turn_off
    device_id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    entity_id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    domain: switch
mode: single

I would probably make the score card values and results a little more complex and weighted after I get a basic version of this running.
But any thoughts or help to get me started would be greatly appreciated.
Thank you!

UPDATE /EDIT :
Turns out I had two issues and the solutions came from two users, Armedad (fixing my template to use set weather_enum = ) and Code-In-Progress (fixing the weather states to the proper unix-style / backend naming vs. the friendly names which got from the sensor’s card on my dashboard). See below …

first, try this format… it doesn’t solve your problem, but you might like it

{% set weather_enum =
{ 'cloudy': 0,
  'partly cloudy': 1,
  'sunny': 2,
  'exceptional': 3,
  'unavailable': -1
  }
%}
{% set weather_state = states('weather.home') %}
{{ weather_enum[ weather_state ] }}

in terms of why you are getting 0, when you go to dev tools - templates and enter

{{states('weather.home')}}

what do you get? I get ‘unavailable’ which would give me 0…

1 Like

Seems the weather states are case sensitive. Cloudy should be cloudy. At least from Openweathermap, I get only lower case. Obviously fixable with a call to title or something like that.

I think that’s the problem with @mames13’s original template as well.

2 Likes

nice!

i updated the code above in accordance to what @code-in-progress said.

if you’re looking at aggregating from multiple services in order to get the wisdom of the crowd, then perhaps just doing an average is what you want…

1 Like

Thank you so much, @armedad and @code-in-progress.
I was getting so frustrated when I posted the question that I resorted to ChatGPT (free version) while I waited for a response, which did not help with the frustration at all… :joy: It was almost comical how much ChatGPT wanted to get deep into the terminal, lots of lines, add-ons, etc. to “fix things.” I even let it try to build me some python just to see if it could do it properly (I’m much more familiar with python) but nope, such a mess.

So, between your set weather_enum method and Code’s heads-up to try different syntax on the states, everything is working—all 3 APIs have running number sensors that output to a final aggregate sensor used by my automations. Go Team Humans!

…And yes, turns out @code-in-progress, the correct syntax is slightly random too; for example, “Partly cloudy” = partlycloudy but “Clear, night” = clear-night , etc. …

2 Likes

great! @code-in-progress found the issue. I just added code beauty points…

2 Likes

The set weather_enum = part was a big help too!

1 Like