Drayton Wiser Home Assistant Integration

I think the fact we are restyling the slider is the problem. Had a look to see if this can be resolved but no success so far. If we keep the style the same, ie have the left and right sliders with the gap in the middle then its fine but with the grey on the right, not sure can be fixed.

Thanks for taking a look.

The high slider colour for passive card is a different element to the same in the auto card ( it is the background slider colour). Also the opacity is different as well, so this causes the difference in the themes.
So I have hard coded them to be a colour/opacity combination that seems to be very close in both light and dark themes.

Here is my yaml with other tweaks to the colours of the extra text and the current temperature depending on the heating/demand/passive states.

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-high-color: #e8e8e8;
          --slider-passive-range-opacity: 1;
          --slider-theme-opacity: 1;
          --extra-info-text: "{%- if state_attr(config.entity, 'is_passive') -%}Passive{%- elif state_attr(config.entity, 'is_boosted') -%}{{ state_attr(config.entity, 'preset_mode') }}{%- elif state_attr(config.entity, 'preset_mode') == 'Comfort' -%}Comfort{%- else -%}{{ states(config.entity) | title }}{%- endif -%}{% if (state_attr(config.entity, 'percentage_demand') | float(0) >0) %}   {{ 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);
            --extra-info-text-color: var(--passive-auto-color);
          {%- 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);
            --extra-info-text-color: var(--passive-heat-color);
          {%- elif is_state(config.entity, 'auto') -%}
            --slider-opacity: var(--slider-theme-opacity);
            --slider-color: var(--slider-high-color);
            --extra-info-text-color: var(--climate-auto-color);
          {%- elif is_state(config.entity, 'heat') -%}
            --slider-opacity: var(--slider-theme-opacity);
            --slider-color: var(--slider-high-color);
            --extra-info-text-color: var(--climate-heat-color);
          {%- 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(--slider-high-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;
          }
        ha-big-number:
          $: |
            {% if state_attr(config.entity, 'is_heating') and
            state_attr(config.entity, 'is_passive') %}
              .value { color: var(--state-climate-heat-cool-color); }
            {% elif state_attr(config.entity, 'is_heating') %}
              .value { color: var(--state-climate-heat-color); }
            {% elif state_attr(config.entity, 'percentage_demand') | float(0) >
            0 %}
              .value { color: var(--state-climate-heat-cool-color); }
            {% endif %}       

Here is an example using my dark theme.

image

And the same using the light theme.

image

Virtually the same - so Iā€™m happy with the result for my themes.

Iā€™m not so sure about the current temperature (big number) colours though. I was trying to replicate what we had in the old card. I think Iā€™ll remove the ha-big-number section and leave that element alone.

Now Iā€™ve just got to port it into your card theme :slight_smile:
Cheers
Mike

When turning on a Drayton Wiser smart plug using the following yaml:

- type: turn_on
  device_id: <device id here>
  entity_id: <entity id here>
  domain: switch

The plug is turning on, but the system log is showing an error:

ā€˜NoneTypeā€™ object has no attribute ā€˜product_typeā€™

Any thoughts please?

Thanks,

John

I have never seen that used before, so have no idea if itā€™s even something that is supported. Just use the regular:

- service: switch.turn_on
  target:
    entity_id: switch.wiser_smart_plug

I agree, I had already looked at this and because the background slider colour runs up the edges of the high slider (stroke) colour, I donā€™t believe there is anything that can be done about this either. The only way around it appears to be not changing the background slider colour.

@Duke_box That outer glow is there on the light theme as well, itā€™s just a lot less noticeable. Iā€™m not sure why the opacity settings are not working for you on the dark theme. Iā€™ll do a bit more testing on that.

Hey @robertwigley

Im not home at the moment but I do remember there was a sticker on the heat switches box and it said ā€œnot suitable for plinth heatersā€ā€¦ Iā€™ll be back home on friday and can check then

as for placing the box, it shouldnt get hot (its rated at 16Amps, and the towel rad is 300-400w - thats 2.5-3.5Amps @240v so way under the rating.

The sparky agrees. What he has is put lots of loose cabling behind the double socket so if I need to repair I can take the socket out, pop up the plastic plasterboard wall box and pull up the heat switch.

if it becomes a pain then I will also have plenty of space to fit it outside under the sockets or in the cupboard.

Upstairs is a little different though. When I get this done Iā€™ll let u know

1 Like

Thanks. Would appreciate you confirming the details on what it says as there is no mention of that in anything I can find online, or in the PDF of the installation instructions.

Iā€™ll get the wife to take a photo. It was a ā€œstick on - after thought - labelā€ on the boxā€¦ I guess theyā€™ve had issues. They should still update their website

1 Like

Unfortunately, the same error gets reported in the log.

Using the following to turn on a Drayton Wiser smart plug:

alias: Turn on guest bedroom air purifier switch
sequence:
  - service: switch.turn_on
    metadata: {}
    data: {}
    target:
      entity_id: switch.wiser_guest_bedroom_air_purifier_switch_2
mode: queued
icon: mdi:air-filter

the result in the log is as follows:

Log details (ERROR)
Logger: homeassistant.components.websocket_api.http.connection
Source: components/websocket_api/commands.py:238
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 12:41:24 PM (2 occurrences)
Last logged: 12:46:24 PM

[546587913280] 'NoneType' object has no attribute 'product_type'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 238, in handle_call_service
    response = await hass.services.async_call(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2149, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2186, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 605, in _service_handler
    response = await self._async_start_run(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 563, in _async_start_run
    script_result = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 594, in _async_run
    return await self.script.async_run(script_vars, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1587, in async_run
    return await asyncio.shield(run.async_run())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1116, in async_run
    await super().async_run()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 426, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 479, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 502, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 476, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 713, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 675, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2149, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2186, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 272, in handle_service
    return await service.entity_service_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 882, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 952, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/config/custom_components/wiser/helpers.py", line 17, in wrapper
    await func(*args, **kwargs)
  File "/config/custom_components/wiser/switch.py", line 510, in async_turn_on
    await self.async_force_update(2)
  File "/config/custom_components/wiser/switch.py", line 213, in async_force_update
    await self._data.async_refresh()
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 276, in async_refresh
    await self._async_refresh(log_failures=True)
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 399, in _async_refresh
    self.async_update_listeners()
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 182, in async_update_listeners
    update_callback()
  File "/config/custom_components/wiser/sensor.py", line 324, in _handle_coordinator_update
    super()._handle_coordinator_update()
  File "/config/custom_components/wiser/sensor.py", line 216, in _handle_coordinator_update
    _LOGGER.debug(f"{self.name} device update requested")
                     ^^^^^^^^^
  File "/config/custom_components/wiser/sensor.py", line 346, in name
    return f"{get_device_name(self._data, self._device_id)} Signal"
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/wiser/helpers.py", line 34, in get_device_name
    if device.product_type == "iTRV":
       ^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'product_type'

Similarly, turning off a radiator using:

      - service: climate.turn_off
        data: {}
        target:
          entity_id: climate.wiser_kitchen

results in the following appearing in the log:

Logger: homeassistant
Source: custom_components/wiser/helpers.py:34
Integration: Drayton Wiser Integration for Home Assistant (documentation, issues)
First occurred: January 19, 2024 at 11:57:15 AM (11589 occurrences)
Last logged: 12:56:09 PM

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 243, in _handle_refresh_interval
    await self._async_refresh(log_failures=True, scheduled=True)
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 399, in _async_refresh
    self.async_update_listeners()
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 182, in async_update_listeners
    update_callback()
  File "/config/custom_components/wiser/sensor.py", line 324, in _handle_coordinator_update
    super()._handle_coordinator_update()
  File "/config/custom_components/wiser/sensor.py", line 216, in _handle_coordinator_update
    _LOGGER.debug(f"{self.name} device update requested")
                     ^^^^^^^^^
  File "/config/custom_components/wiser/sensor.py", line 346, in name
    return f"{get_device_name(self._data, self._device_id)} Signal"
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/wiser/helpers.py", line 34, in get_device_name
    if device.product_type == "iTRV":
       ^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'product_type'

When you issue a command to the hub, it sends the command and then calls an update to get the current status.

This seems to be an error when it is calling the update after the command. I suspect, it is not getting a valid update data set for some reason but not a failed refresh. Ie it is getting an update but some data is missing.

Can you confirm versions of HA and the integration and also your hub type and firmware version.

We do not see this in general.

Hopefully this provides all the version information requested:

Home Assistant
Core: 2024.1.3
Supervisor: 2023.12.1
Frontend: 20240104.0
Drayton Wiser Integration diagnostics:

  "home_assistant": {
    "installation_type": "Home Assistant Supervised",
    "version": "2024.1.3",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.11.6",
    "docker": true,
    "arch": "aarch64",
    "timezone": "Europe/London",
    "os_name": "Linux",
    "os_version": "4.4.194",
    "supervisor": "2023.12.1",
    "host_os": "Debian GNU/Linux 11 (bullseye)",
    "docker_version": "20.10.12",
    "chassis": "",
    "run_as_root": true
  },

    "wiser": {
      "version": "3.4.1",
      "requirements": [
        "aioWiserHeatAPI==1.5.5"
      ]
    },
HubR firmware: 3.14.0
Model identifier: WT724R1S0902

3.4.2 is the latest version of the Wiser integration, includes:

ā€œReverted to using aiohttp for communication and resolved issues caused by HA2023.12ā€

I would try updating the integration before doing any further troubleshooting.

1 Like

Hi Robert,

Thanks for your response.
Looking at your code, it seems to me, you are applying the --slider-theme-color to the .high element of the card. This is fine for a card that is in ā€œhi/loā€ configuration like a Passive card, but the Auto or Heat cards do not have that element. It is, as you say, the background slider element and the opacity isnā€™t applied to that.
However, I tried doing just that and it made only a slight difference (as to be expected as they are 0.3 (light) & 0.38 (dark)).
The other issues is, again as you have stated, you cannot detect the theme the card is being presented in. So adjusting the opacity based on that is a none starter.
I have got round the opacity issue by just coding it as 1.
With regard to the slider colours, I have made a new variable, --slider-high-color and applied it to the high- colour on the Passive card and the background slider colour on the Auto/Heat cards, so making them the same irrespective of the card type and the theme.
you can see this in the code I posted above.

Since then I have changed some of my colour preferences.

Cheers Mike

Thanks @Angelo_Santagata. I suspect the lack of plinth heaters on the market that only have a simple on/off control may be the reason for this. So many (all the better makes) seem have their own proprietary wireless thermostats or remotes that probably donā€™t work with it. This may potentially be the reason for the sticker being added i.e. as a blanket it doesnā€™t work with plinth heaters, because for the majority, it probably doesnā€™t.

Edit: I have since phoned a few plinth heater manufacturers Myson, Consort and Smiths. Myson and Consort said straight off no, their products are not compatible. However, a very helpful chap at Smiths said although their products are not officially compatible, he was actually using one with the Wiser Electrical Heat Switch himself. :laughing: He said it required a manual bypass of the wireless control module inside the unit.

Another option I found is this from Eterna, which I am pretty sure will work as it is a simple on/off model. There are other models with just on/off controls e.g. on Amazon, but they have very mixed reviews on quality and reliability. The Eterna one is clearance at Toolstation, but has generally good reviews and is still available from other suppliers.

I also phoned Drayton and the girl had to go away and check, but said if it fell within the 16A rating, it would work, which I think is probably just a standard response. They seemed to know less that me. :rofl:

1 Like

Yes, the high element of the card doesnā€™t exist in non-passive mode, but you shouldnā€™t need to apply the opacity to what is the slider background for Auto or Heat. It should already match. I will need to test further, as I am not using the dark theme.

For the dark theme, please can you try:

--slider-theme-opacity: 0.46;

image

It looks like I had incorrectly assumed that --dark-disabled-opacity was the correct variable. Doing a colour sample in Paint.net returns the same values (RGB 41,41,41 or Hex #292929) for both the passive high slider and the auto background slider with that opacity applied.

This will only work with the dark theme though. If you run different themes on different devices, you may have to find a similar in between colour that works with both, but is not exact and remove the opacity, which it like it looks like you are already doing. Iā€™ll do a bit more research to see if there is any way to detect the theme in use, but I think itā€™s unlikely that this is going to be possible.

I can confirm, using the same colour sample method, that --light-disabled-opacity is correct when used for the light theme and both the passive high slider and the auto background slider return (RGB 235,235,235 or Hex #ebebeb).

@msp1974 I havenā€™t had a chance to test the card-mod themes yet. Iā€™ll try and find time in the next few days.

Yes - thatā€™s what I was saying all along - but thanks for confirming.
I now use the stock var(--disabled-color) and live with it being a bit darker but that enables me to see the actual temperature on the slider when itā€™s in the ā€œhigh slider sectionā€ which with my original choice of #e8e8e8 was very hard to see.
And it works across both my light (HA default) and my dark (customised slate (from HACS)) themes. All the same colour for Passive and Auto/Heat in both themes. Which was the aim in the first place.

And I can confirm that @msp1974ā€™s card-mod them applied to each card works. I have had to refresh the browser sometimes to make it stick but I suspect that is because Iā€™ve been changing themes trying to solve the above issue.

Thanks to you both for your input.

Sorry, I hadnā€™t realised you were using different themes on different devices. Iā€™ll let you know if I find a way to detect the theme in use, but, as I said, think itā€™s unlikely.

I guess the other ā€˜clunkyā€™ option is to create two dashboards configured differently for dark and light themes and view the corresponding one as needed? Definitely clunky, but I am trying to think of options for anyone else using a mixture of themes who want the colours to match exactly.

It appears it might be possible, but again clunky, using browser-mod. See the post here.

The only other way I can think it might be possible to do this, is if thereā€™s a way to evaluate whether a variable is set to a specific value e.g. if --card-background-color changes and can be tested for itā€™s value.

There is a feature request open for a binary sensor for this exact thing to be included in HA. Feel free to vote for itā€™s inclusion here.

Sorry I may have misled you.
I donā€™t use different themes on different devices. I use the same 2 themes on all devices but switch through an automation at sunset (or twilight whatever, I canā€™t remember). Itā€™s the fact the colours changed on the change of theme that I didnā€™t want. and they werenā€™t consistent between Passive and Auto/heat.
Anyway I got it working the way I want by changing the background colour to the same as the high slider colour(on the Passive) on the Auto/Heat cards.

But you have highlighted a FR that I will vote for :slight_smile:

Ah, right, I see. Time dependent theming. The same principles apply though. Thereā€™s no easy and completely colour accurate solution I can see to this. Maybe someone else will have an idea on how to determine the theme in use.