Drayton Wiser Home Assistant Integration

@msp1974 Have I misunderstood, but is the is-heating-color variable supposed to allow us to choose any color for the radial heating glow? I was excited to see this, as I’d like to switch it off on a misbehaving non-wiser thermostat card that constantly reports as heating even when it isn’t. I tried assigning it var(--card-background-color), which had no effect. I thien tried a few others and it didn’t change from the default var(--deep-orange-color).

On a separate topic, and I am not sure if it’s intentional or just an oversight, but while working on these new thermostat card modifications, I have noticed that when you switch the thermostat off, the hvac_action attribute still reports idle, which is what is shown on the card above the temperature. I can’t remember if the old card in 2023.11.x and below used to do this or not, or something has changed in the new card to use that attribute instead. Maybe I just never noticed before. Either way, I think this should probably be changed to off when it is switched off, so that it’s displayed above the temperature, assuming you agree, there’s not another reason for it to report as idle and it’s possible to do this of course.

I htink Mark has already comprehensively answered your question. :slight_smile:

@Duke_box Going back to the high slider using var(--disabled-color) and making it work perfectly with both light and dark themes, I think the reason you were struggling is because it looks like they use different opacities. It looks like 0.4 for opacity I suggested previously was close for both, but not correct for either. I spotted this on the themes and colours link I have posted before:

/* opacity for dark text on a light background */
--dark-divider-opacity: 0.12;
--dark-disabled-opacity: 0.38; /* or hint text or icon */
--dark-secondary-opacity: 0.54;
--dark-primary-opacity: 0.87;

/* opacity for light text on a dark background */
--light-divider-opacity: 0.12;
--light-disabled-opacity: 0.3; /* or hint text or icon */
--light-secondary-opacity: 0.7;
--light-primary-opacity: 1;

So I think you probably want to use this on a light theme:

{%- if state_attr(config.entity, 'is_passive') -%}
  .high {
      stroke: var(--disabled-color) !important;
      opacity: var(--dark-disabled-opacity) !important;
  }

And this on a dark theme:

{%- if state_attr(config.entity, 'is_passive') -%}
  .high {
      stroke: var(--disabled-color) !important;
      opacity: var(--light-disabled-opacity) !important;
  }

Or vice-versa. My monitor is too old and not colour accurate enough that I can’t really be sure.

I suspect there must be a way to auto-detect whether the light or dark theme is active and select the correct variable accordingly, but I don’t know how to do that and haven’t started investigating yet.

Yes. It definitely works for me. Did you add the full updated card_mod code?

This did not use to show on the old card and need to look at why. Does the attribute on the room entity show idle or off?

OK, thanks for confirming I had not misunderstood. No, not completely. I am pretty sure I copied the bits I needed though. I will try again with the full updated code and work backwards.

Ah, so it’s changed in the new card then. The hvac_action, from what I can make out, seems to be what is displayed above the temperature now then and when it’s off, it shows as Idle, as that is the state of hvac_action.

image

I guess the old card hid this when off. This can also be made to do the same using card_mod if you need. Just set the label visibility to hidden when state is off.

I also think the card_mod code can be simplified to how i did originally now we can control the glow colour. I will have a look at that and how we can make it a template in the next few days.

Ideally I would like it to display off though. I take it this can’t be changed in the integration then? Can card-mod change the text in the default label to say off instead of idle?

Although I suppose changing it in the integration would technically be a breaking change and others may not want the same, it does seem cleaner than using card-mod to do it, if it’s possible with card-mod of course.

I still use an old custom card based on the Nest thermostat look, but have a markdown card below where I pull in hvac_action, state and any presets:
image

If the label can be set to use a template, this is what I have:

{{ state_attr ('climate.wiser_living_room', 'hvac_action') | capitalize }} ({{ states ('climate.wiser_living_room') | capitalize }}) {{ state_attr('climate.wiser_living_room', 'preset_mode') | capitalize }}

That’s an interesting solution, using a Markdown card. What are you using to create the buttons for boost etc? It doesn’t look like button cards in a grid.

They are button cards in a horizontal-stack card using card-mod to set no background:

            - type: horizontal-stack
                  cards:
                    - type: button
                      card_mod:
                        style: |
                          ha-card {
                            background: none !important;
                            border-radius: 0px !important;
                            font-size: 0.85em !important;
                          }
                      tap_action:
                        action: call-service
                        service: climate.set_preset_mode
                        service_data:
                          preset_mode: Boost 30m
                        target:
                          entity_id: climate.wiser_living_room
                      icon: mdi:thermometer-plus
                      entity: climate.wiser_living_room
                      name: Boost 30m
1 Like

From my testing it seems that the radial heating glow is only changed when the thermostat card is not nested inside other cards e.g. vertical-stack and grid.

type: vertical-stack
cards:
  - type: markdown
    content: '## Rooms'
  - type: grid
    square: false
    columns: 2
    cards:
      - type: custom:vertical-stack-in-card
        cards:
          - type: thermostat
            entity: climate.living_room_climate
            name: Living Room
            show_current_as_primary: true
            features:
              - type: climate-hvac-modes
                hvac_modes:
                  - auto
                  - heat
                  - 'off'

Ah, we had this with the old card too. I’ll have to look back and find our fix (unless you.get there first! :grinning:)

1 Like

Unfortunately, I’m struggling to find how to fix it when nested.

So we are singing from the same hymn sheet, I’ve modified your template code a little to be, what I think is, easier to understand by tweaking the variable names.

I’ve also added a new variable for --high-slider-opacity, which appears to need to be changed dependent on whether the light or dark theme is selected (as per my previous post on this). Unfortunately, it doesn’t appear to be possible detect which theme is in use and select this automatically.

The opacity values previously using 0.75 are now correct, as far as I can tell. There should have been no opacity (i.e. 1) applied to these as there is not in the standard card settings.

For my own customisation, I have changed passive-mode-text to be always shown, hence the variable rename to extra-info-text, not just when in Passive Mode, as I think it’s nice to display the HVAC mode and demand regardless. The dynamicity of the text to be displayed is handled by a template in the variable itself.

Lastly, I want the radial heating glow to show when there is demand and not just when heating, so I have modified that too, although the glow is currently not working when nested in other cards (hence my screenshots are from non-nested cards, where this works correctly).

Here’s my current YAML and some screenshots:

card_mod:
  style:
    ha-state-control-climate-temperature:
      .: |
        :host {
          {# Colours #}
          --climate-auto-color: var(--green-color);
          --climate-heat-color: var(--deep-orange-color);
          --passive-auto-color: var(--light-green-color);
          --passive-heat-color: var(--amber-color);
          --radial-heating-glow-color: var(--deep-orange-color);
          --label-text-highlight-color: var(--state-climate-heat-color, inherit);
          --high-slider-opacity: var(--light-disabled-opacity);

          {# Buttons and extra info text #}
          --button-visibility: hidden;
          --extra-info-text: "{%- if state_attr(config.entity, 'is_passive') -%}Passive{%- elif is_state(config.entity, 'heat') -%}Manual{%- else -%}{{ states(config.entity) | title }}{%- endif -%}{%- if not is_state(config.entity, 'off') %} ⸱ {{ state_attr(config.entity, 'percentage_demand') }}%{%- endif -%}";
          --extra-info-text-color: var(--action-color);

          {# DO NOT MODIFY BELOW HERE #}
          --state-climate-auto-color: var(--climate-auto-color, --green-color);
          --state-climate-heat-color: var(--climate-heat-color, --deep-orange-color);
        }
      $:
        .: |
          {# Set the radial heating glow colour and show it when there is demand even if it's not actively heating #}
          {%- if (state_attr(config.entity, 'percentage_demand') | float(0) > 0) -%}
            div.container.lg {
              --action-color: var(--radial-heating-glow-color) !important;
            }
          {% endif %}

          {# Highlight the label text when there is demand even if it's not actively heating #}
          {%- if (state_attr(config.entity, 'percentage_demand') | float(0) > 0) -%}
            .label { color: var(--label-text-highlight-color) !important; }
          {%- endif -%}

          {# Set the buttons visibility and display the extra info text #}
          .buttons { visibility: var(--button-visibility); }
          .info > p:last-of-type::after { content: "\a" var(--extra-info-text); white-space: pre; color: var(--extra-info-text-color) }
        ha-control-circular-slider:
          $: |
            {# Set the slider colours for Passive Mode #}
            {%- if state_attr(config.entity, 'is_passive') -%}
              .high {
                  stroke: var(--disabled-color) !important;
                  opacity: var(--high-slider-opacity) !important;
              }
              {%- if is_state(config.entity, 'auto') -%}
                .background {
                  stroke: var(--passive-auto-color) !important;
                  opacity: 1 !important; 
                }
                .low {
                  stroke: var(--passive-auto-color) !important;
                  opacity: 0.5 !important; 
                }
              {%- elif is_state(config.entity, 'heat') -%}
                .background {
                  stroke: var(--passive-heat-color) !important;
                  opacity: 1 !important; 
                }
                .low {
                  stroke: var(--passive-heat-color) !important;
                  opacity: 0.5 !important; 
                }
              {%- endif -%}
            {%- endif -%}
    hui-card-features $ hui-climate-hvac-modes-card-feature $ ha-control-select:
      $: |
        {# Set the HVAC mode colours for Passive Mode #}
        {%- if state_attr(config.entity, 'is_passive') -%}
          #option-auto::before {
            background-color: var(--passive-auto-color)
          }
          #option-heat::before {
            background-color: var(--passive-heat-color)
          }
        {%- endif -%}

image

Ok, taking your card-mod and some further simplification from me, try this.

card_mod:
  style:
    ha-state-control-climate-temperature:
      .: |
        :host {
          {# Colours #}
          --climate-auto-color: var(--green-color);
          --climate-heat-color: var(--deep-orange-color);
          --passive-auto-color: var(--light-green-color);
          --passive-heat-color: var(--amber-color);
          --radial-heating-glow-color: var(--deep-orange-color);
          --label-text-highlight-color: var(--state-climate-heat-color, inherit);
          --high-slider-opacity: var(--light-disabled-opacity);

          {# Buttons and extra info text #}
          --button-visibility: hidden;
          --extra-info-text: "{%- if state_attr(config.entity, 'is_passive') -%}Passive{%- elif is_state(config.entity, 'heat') -%}Manual{%- else -%}{{ states(config.entity) | title }}{%- endif -%}{%- if not is_state(config.entity, 'off') %} ⸱ {{ state_attr(config.entity, 'percentage_demand') }}%{%- endif -%}";
          --extra-info-text-color: var(--action-color);

          {# DO NOT MODIFY BELOW HERE #}
          --slider-color:var(--disabled-color);
          --slider-opactity: 0.3;
          {% if state_attr(config.entity, 'is_passive') and is_state(config.entity, 'auto') -%}
            --slider-color: var(--passive-auto-color);
            --state-climate-auto-color: var(--slider-color);
            --slider-opactity: 0.75;
          {% elif state_attr(config.entity, 'is_passive') and is_state(config.entity, 'heat') -%}
            --slider-color: var(--passive-heat-color);
            --state-climate-heat-color: var(--slider-color);
            --slider-opactity: 0.75;
          {% endif %}
        }
      $:
        .: >
          {# Set the label colour and show it when there is demand even if it's not actively heating #}
          {%- if (state_attr(config.entity,'percentage_demand') | float(0) > 0) -%}
            div.container {
              .label { color: var(--label-text-highlight-color) !important; }
            }
          {% endif %}

          {# Set the buttons visibility and display the extra info text #}
          .buttons { visibility: var(--button-visibility); }

          .info > p:last-of-type::after { content: "\a" var(--extra-info-text);
          white-space: pre; color: var(--extra-info-text-color) }
        ha-control-circular-slider $: |
          :host {
            --control-circular-slider-high-color: var(--disabled-color) !important;
            --control-circular-slider-low-color: var(--slider-color) !important;
            --control-circular-slider-background: var(--slider-color) !important;
            --control-circular-slider-background-opacity: var(--slider-opactity) !important;
            {# Set radial glow color and show it when there is demand even if it's not actively heating #}
            {% if (state_attr(config.entity, 'percentage_demand') | float(0) > 0) %}
                --action-color: var(--radial-heating-glow-color) !important;
            {% endif %}
          }
2 Likes

Thanks @msp1974 . I’ve tested the new code and it now works when the thermostat card is nested. :partying_face: :clap:

I have made a couple of minor modifications, mainly moving the opacity values to variables, so these can be adjusted easily, to allow for the difference between light and dark themes having different opacities. However, the opacity value for --slider-theme-opacity does not appear to be respected when in Passive Mode, no matter what it’s set to, meaning the grey --disabled-color appears darker than it should be. Not a massive big deal, as it’s not very noticeable, but it would be nice to correct it if possible.

card_mod:
  style:
    ha-state-control-climate-temperature:
      .: |
        :host {
          {# Variables for colours, opacity, extra info text and button visibility #}
          --climate-auto-color: var(--green-color);
          --climate-heat-color: var(--deep-orange-color);
          --passive-auto-color: var(--light-green-color);
          --passive-heat-color: var(--amber-color);
          --radial-glow-color: var(--deep-orange-color);
          --label-text-highlight-color: var(--deep-orange-color, inherit);
          --slider-passive-range-opacity: 1;
          --slider-theme-opacity: var(--light-disabled-opacity);
          --extra-info-text: "{%- if state_attr(config.entity, 'is_passive') -%}Passive{%- elif is_state(config.entity, 'heat') -%}Manual{%- else -%}{{ states(config.entity) | title }}{%- endif -%}{%- if not is_state(config.entity, 'off') %} ⸱ {{ state_attr(config.entity, 'percentage_demand') }}%{%- endif -%}";
          --extra-info-text-color: var(--action-color);
          --button-visibility: hidden;
          {# DO NOT MODIFY BELOW HERE #}
          --slider-color:var(--disabled-color);
          --slider-opacity: var(--slider-theme-opacity);
          {%- if state_attr(config.entity, 'is_passive') and is_state(config.entity, 'auto') -%}
            --slider-color: var(--passive-auto-color);
            --state-climate-auto-color: var(--slider-color);
            --slider-opacity: var(--slider-passive-range-opacity);
          {%- elif state_attr(config.entity, 'is_passive') and is_state(config.entity, 'heat') -%}
            --slider-color: var(--passive-heat-color);
            --state-climate-heat-color: var(--slider-color);
            --slider-opacity: var(--slider-passive-range-opacity);
          {%- endif -%}
        }
      $:
        .: |
          {# Set the label colour and show it when there is demand even if it's not actively heating #}
          {%- if (state_attr(config.entity,'percentage_demand') | float(0) > 0) -%}
            div.container {
              .label { color: var(--label-text-highlight-color) !important; }
            }
          {%- endif -%}
          {# Set the buttons visibility and display the extra info text #}
          .buttons { visibility: var(--button-visibility); }
          .info > p:last-of-type::after { content: "\a" var(--extra-info-text); white-space: pre; color: var(--extra-info-text-color) }
        ha-control-circular-slider $: |
          :host {
            {# Set the slider colours #}
            --control-circular-slider-high-color: var(--disabled-color) !important;
            --control-circular-slider-low-color: var(--slider-color) !important;
            --control-circular-slider-background: var(--slider-color) !important;
            --control-circular-slider-background-opacity: var(--slider-opacity) !important;
            {# Set the radial glow colour and show it when there is demand even if it's not actively heating #}
            {%- if (state_attr(config.entity, 'percentage_demand') | float(0) > 0) -%}
              --action-color: var(--radial-glow-color) !important;
            {%- endif -%}
          }
1 Like

Honestly. I get it working and then you mess and i have to sort it out! :rofl::rofl::rofl::rofl:

I’ll have a look when i get a chance. Think its looking pretty good now though. Still trying to get my head around card-mod-theme which would be much easier to use.

2 Likes

You can use your code if it’s quicker and/or easier for you to test, to save having to look through mine. :slight_smile: Just change the --slider-opactity value (I also fixed the extra ‘t’ in opacity) from 0.3 to e.g.0.9 and you should see that it doesn’t change. In fact, it would probably be better to test this way to make sure I haven’t done something stupid. :laughing:

Yes, it’s fantastic. Other than the opacity thing, which is minor and can be corrected by changing the colour instead if needed, it’s pretty much perfect and actually better than what I had before with the classic thermostat card. Thank you again for all your work on this.

I think what it needs to fix it is an additional line in the bottom section where the slider colours are set:

--control-circular-slider-high-opacity: var(--slider-opacity) !important;

But I don’t know what the real variable is for --control-circular-slider-high-opacity, or if there is one. I certainly can’t find it in the browser code inspector.

I think I got it. :tada: This may not be the best way to do this, but it seems to work.

card_mod:
  style:
    ha-state-control-climate-temperature:
      .: |
        :host {
          {# Variables for colours, opacity, extra info text and button visibility #}
          --climate-auto-color: var(--green-color);
          --climate-heat-color: var(--deep-orange-color);
          --passive-auto-color: var(--light-green-color);
          --passive-heat-color: var(--amber-color);
          --radial-glow-color: var(--deep-orange-color);
          --label-text-highlight-color: var(--deep-orange-color, inherit);
          --slider-passive-range-opacity: 1;
          --slider-theme-opacity: var(--light-disabled-opacity);
          --extra-info-text: "{%- if state_attr(config.entity, 'is_passive') -%}Passive{%- elif is_state(config.entity, 'heat') -%}Manual{%- else -%}{{ states(config.entity) | title }}{%- endif -%}{%- if not is_state(config.entity, 'off') %} ⸱ {{ state_attr(config.entity, 'percentage_demand') }}%{%- endif -%}";
          --extra-info-text-color: var(--action-color);
          --button-visibility: hidden;
          {# DO NOT MODIFY BELOW HERE #}
          --slider-color:var(--disabled-color);
          --slider-opacity: var(--slider-theme-opacity);
          {%- if state_attr(config.entity, 'is_passive') and is_state(config.entity, 'auto') -%}
            --slider-color: var(--passive-auto-color);
            --state-climate-auto-color: var(--slider-color);
            --slider-opacity: var(--slider-passive-range-opacity);
          {%- elif state_attr(config.entity, 'is_passive') and is_state(config.entity, 'heat') -%}
            --slider-color: var(--passive-heat-color);
            --state-climate-heat-color: var(--slider-color);
            --slider-opacity: var(--slider-passive-range-opacity);
          {%- endif -%}
        }
      $:
        .: |
          {# Set the label colour and show it when there is demand even if it's not actively heating #}
          {%- if (state_attr(config.entity,'percentage_demand') | float(0) > 0) -%}
            div.container {
              .label { color: var(--label-text-highlight-color) !important; }
            }
          {%- endif -%}
          {# Set the buttons visibility and display the extra info text #}
          .buttons { visibility: var(--button-visibility); }
          .info > p:last-of-type::after { content: "\a" var(--extra-info-text); white-space: pre; color: var(--extra-info-text-color) }
        ha-control-circular-slider $: |
          :host {
            {# Set the slider colours #}
            --control-circular-slider-high-color: var(--disabled-color) !important;
            --control-circular-slider-low-color: var(--slider-color) !important;
            --control-circular-slider-background: var(--slider-color) !important;
            --control-circular-slider-background-opacity: var(--slider-opacity) !important;
            {# Set the radial glow colour and show it when there is demand even if it's not actively heating #}
            {%- if (state_attr(config.entity, 'percentage_demand') | float(0) > 0) -%}
              --action-color: var(--radial-glow-color) !important;
            {%- endif -%}
          }
          .high {
            opacity: var(--slider-theme-opacity) !important;
          }

If using the dark theme you need to use --dark-disabled-opacity in place of --light-disabled-opacity.

Hi,

This code of yours is getting more complicated and your updates are too frequent for me to try them out before your next post. Sloooooow down :slight_smile: :wink: :wink:

BTW Why don’t you now use the features bit of the code?

I noticed your typo with ‘opactity’ but that just highlighted something else which I might have misled you with.

Because of your typo, I could see the effect of the different theme on the difference of the high slider disabled colour between HVAC modes.
I can live with the minor difference between the themes as they are not visible at the same time but it looks to me that no matter what the theme the high slider is subtly different between Heat and Auto.
I only noticed because of your typo :grin:

Here’s an example using your posted code, after the typo is corrected, ( before your last post) of the light theme, I hope you can see the difference between the disabled colours of my conservatory (passive, HVAC heat) and my kitchen ( non-passive, HVAC auto)

image

And here is the same thing using a dark theme - a subtle difference between HVAC modes

image

This is the difference I was meaning in our original discussion when I talked about themes.
I agree that this is an opacity issue but are we talking about the same thing? I cannot see how this would be different depending on HVAC mode when I inspect the card but, to me there is a visible difference.

@msp1974 I would welcome your thoughts on this.

Cheers
Mike