MindrustUK / Heatmiser-for-home-assistant

Heatmiser Neo-Hub / Neostat support for home-assistant.io
88 stars 33 forks source link

Timer hold 182 #187

Closed ocrease closed 1 month ago

ocrease commented 1 month ago

Hi @MindrustUK, this is an attempt to bring back the timer switch functionality that was lost on the upgrade to v1.5 (#182) . I have added the switch back in which reflects the state of the timer_on state. Turning on the switch from the UI sets a hold of 30 minutes and turning off the switch removes the hold. Additionally, I have added a timer_hold_on service that can allow users to set a hold with a custom duration.

I think this change makes the 'HeatmiserNeoTimerOutputActiveSensor' redundant but I haven't removed it in this PR.

image image

You'll notice I added

self._attr_supported_features = SirenEntityFeature.DURATION

Which borrows the DURATION feature from the siren entity. I'm using this to filter the entities in the service call, otherwise all switches from this integration appear in the selector. I believe that while its possible to create custom features, the filtering only works with the ones defined by Home Assistant itself.

Feel free to use it as is, make changes or give me feedback so I can make the changes.

MindrustUK commented 1 month ago

@ocrease A few niggles, I appreciate the effort if you can get these resolved we can pull this into 1.5 as a sticking plater. I'll probably retain the service but as per our other conversation there's a desire to surface hold configuration via the UI which still needs some level of attention, although as you've suggested maybe this is a consumer of the service rather than additional entities as part of this. Will check with the requesters in due course.

ocrease commented 1 month ago

@MindrustUK I have made the changes you requested.

Regarding surfacing the hold configuration, here is an example of how a user can do this already with a service:

image

type: entities
entities:
  - type: conditional
    conditions:
      - entity: sensor.kitchen_heatmiser_neostat_v2_hold_active
        state: "off"
    row:
      name: Kitchen
      icon: mdi:thermostat
      type: button
      action_name: Hold
      tap_action:
        action: perform-action
        perform_action: script.hold_thermostat
        data:
          target_entity: climate.kitchen
          hold_duration: input_datetime.kitchen_boost_time
          hold_temperature: input_number.kitchen_boost_temperature
  - type: conditional
    conditions:
      - entity: sensor.kitchen_heatmiser_neostat_v2_hold_active
        state: "off"
    row:
      entity: input_datetime.kitchen_boost_time
      name: Duration
  - type: conditional
    conditions:
      - entity: sensor.kitchen_heatmiser_neostat_v2_hold_active
        state: "off"
    row:
      entity: input_number.kitchen_boost_temperature
      name: Temperature
  - type: conditional
    conditions:
      - entity: sensor.kitchen_heatmiser_neostat_v2_hold_active
        state: "on"
    row:
      name: Kitchen
      icon: mdi:thermostat
      type: button
      action_name: Hold Off
      tap_action:
        action: perform-action
        perform_action: heatmiserneo.hold_off
        target:
          entity_id: climate.kitchen
  - type: conditional
    conditions:
      - entity: sensor.kitchen_heatmiser_neostat_v2_hold_active
        state: "on"
    row:
      entity: sensor.kitchen_heatmiser_neostat_v2_hold_time_remaining
      name: Remaining
  - type: conditional
    conditions:
      - entity: sensor.kitchen_heatmiser_neostat_v2_hold_active
        state: "on"
    row:
      entity: climate.kitchen
      name: Hold Temperature
      attribute: hold_temp
      type: attribute
title: Kitchen Boost

And a helper script

alias: Hold Thermostat
sequence:
  - action: heatmiserneo.hold_on
    target:
      entity_id: "{{ target_entity }}"
    data:
      hold_duration: "{{ states(hold_duration) }}"
      hold_temperature: "{{ states(hold_temperature) | float }}"
fields:
  target_entity:
    selector:
      entity:
        multiple: true
        filter:
          domain: climate
          integration: heatmiserneo
    name: target entity
    required: true
  hold_duration:
    selector:
      entity:
        filter:
          domain: input_datetime
    name: Hold Duration
    required: true
  hold_temperature:
    selector:
      entity:
        filter:
          domain: input_number
    name: Hold Temperature
    required: true
description: ""

I don't actually plan to use the card (or hold on the thermostat), hence it's not very pretty! Note that the helper script is required because in this example I am using the standard entities card which does not allow evaluation of templates for the service call. I'm sure there are custom cards that would allow it.

Is there a discussion that talks about the requirement to surface the parameters as configuration on the entities itself? I've seen some discussions in #119 and #9, but these already show that it can be done with input number / input selects. It also shows the different requirements that users might have, some might want a dropdown of predefined durations, others will want an exact number etc. Seems better to let the users use the home assistant features to build exactly what they want.

Having said that, it might be nice to be able to configure the default duration when using the switch. But perhaps it would be better to do it as part of the config flow? I can investigate that if you want.

Also, are there any features/issues that you would like help with? It probably makes sense if they are things you are not actively working on so that I don't step on your toes. For reference I have a NeoHub V2 and seven neoStat V2, one of which operates as a timer to control hot water. Some that caught my eye are regarding using websockets, sync neo stat clocks/ntp, holiday mode, long terms statistics.

MindrustUK commented 1 month ago

Thanks for your work @ocrease !

Including the card as a sample in the repo as a quick start for users myabe good enough to satisfy the overall requirement.

Discussions are pretty much in the threads you've identified, and as seen in dev there are input numbers and selects in place as part of this. We can totally leave this to the users, although they may struggle with how to achieve this. It's why I like the idea of bundling an optional card.

My original intention was to have these functions bundled up into a configuration flow that would enable / disable the controls as users required. We can set the default duration as a preference in a similar way.

At this stage we maybe entirely over engineering the simplicity of "Give me an input box to put the temperature in and a field to put in the duration" automatically available in the integration.

On investigating features and issues, if you've got some free time and want to forward me some contact details we can setup a screenshare and I can walk you through what's already done but not ready for public consumption along with my internal roadmap. Websockets is essentially ready to go and just needs some config flow changes I've not got round to publishing due to other dependencies. NTP needs some configuration flow and execution at cadence. I've not looked at Holiday Mode or Long Term stats much at all so these maybe the 'cleanest' features to pursue.

In the mean time I'll get this merged in which should hopefully create some parity with the version 1 branch.