mathieu-mp / homeassistant-intex-spa

Home Assistant integration for Intex Spa
https://github.com/mathieu-mp/homeassistant-intex-spa
MIT License
32 stars 6 forks source link

add sensor spa_target_temperature and spa_connected #52

Closed FreezyExp closed 1 year ago

FreezyExp commented 1 year ago

Is your feature request related to a problem? Please describe.

I would like to automate the sanitizer to activate after X minutes of spa use.

  1. Keeping track of the time the target temperature is high.
  2. When the target is set low, we can trigger a check for the number of minutes.
  3. If the target time was reached, activate the sanitizer and reset the counter.

Describe the solution you'd like

Common automation scenarios should be simplified by exposing a few more sensors from available data.

Target temperature could be made available for the threshold sensor helper, or a statistics sensor added to the intergration directly.

It would also be great to have a 'connected' state, as the intergration probably has a better 'feel' for the connection state then my router HA intergration makes available to me.

consider https://developers.home-assistant.io/docs/core/entity/sensor/#long-term-statistics with type measurement

Describe alternatives you've considered

I can create an extensive sensor configuration, but having these available in the platform would reduce user-setup for common scenarios.

Additional context

The sensor.spa_current_temperature can be added to a helper of type 'threshold sensor', which can then be used by a statistics sensor. This would give us relevant usage time data and allow further automations to trigger.

Add a threshold sensor in the helpers section of HA settings, call it 'Spa in use' It will become true if the target temperature (I am currently using 'spa_current_temperature' as it is already available)

Adding the following sensor to configuration.yaml :

sensor:
  - platform: history_stats
    name: Spa In Use Time
    entity_id: binary_sensor.spa_in_use
    state: "on"
    type: time

The next step would be creating an automation around the usage time, possibly using a minutes counter or 'last santizer' timestamp or something to check for trigger conditions.

FreezyExp commented 1 year ago

I added some helper value and some automation scripts to get close to what I would like to have / see in HA.

input boolean spa_in_use input datetime spa_in_use_start_time input number spa target temperature

then two automations:

alias: Spa - Sync Input to HVAC
description: ""
trigger:
  - platform: state
    entity_id:
      - input_number.spa_target_temperature
condition:
  - condition: template
    value_template: >-
      {{ states.input_number.spa_target_temperature | int(0) != 
      state_attr('climate.spa', 'temperature') | int(0)}}
action:
  - service: climate.set_temperature
    data:
      hvac_mode: heat
      temperature: "{{ states('input_number.spa_target_temperature')| int(34) }}"
    target:
      entity_id: climate.spa
mode: single
alias: Spa - Sync HVAC to Input
description: ""
trigger:
  - platform: device
    device_id: 3cd3c4131130348f6f7886d2cf322146
    domain: climate
    entity_id: climate.spa
    type: hvac_mode_changed
    to: heat
  - platform: numeric_state
    entity_id: climate.spa
    attribute: temperature
    above: input_number.spa_target_temperature
  - platform: numeric_state
    entity_id: climate.spa
    attribute: temperature
    below: input_number.spa_target_temperature
condition: []
action:
  - service: input_number.set_value
    data_template:
      value: "{{ state_attr('climate.spa', 'temperature') | int(0) }}"
    target:
      entity_id: input_number.spa_target_temperature
  - if:
      - condition: numeric_state
        entity_id: climate.spa
        attribute: temperature
        above: 34
    then:
      - service: input_boolean.turn_on
        data: {}
        target:
          entity_id: input_boolean.spa_in_use
      - service: input_datetime.set_datetime
        data:
          timestamp: "{{ now().timestamp() }}"
        target:
          entity_id: input_datetime.spa_in_use_start_time
    else:
      - service: input_boolean.turn_off
        data: {}
        target:
          entity_id: input_boolean.spa_in_use
mode: single
FreezyExp commented 1 year ago

Here is what I came up with for the dashboard:

type: vertical-stack
cards:
  - type: entities
    entities:
      - entity: sensor.spa_current_temperature
        secondary_info: last-updated
        icon: mdi:water-thermometer
        name: Current Temperature
      - entity: input_number.spa_target_temperature
        name: Target Temperature
        icon: mdi:target
    show_header_toggle: false
    state_color: false
  - type: horizontal-stack
    cards:
      - show_name: false
        show_icon: true
        type: button
        tap_action:
          action: call-service
          service: input_number.decrement
          target:
            entity_id: input_number.spa_target_temperature
          data: {}
        show_state: false
        icon_height: 48px
        icon: mdi:thermometer-minus
        hold_action:
          action: none
      - show_name: true
        show_icon: false
        type: button
        tap_action:
          action: call-service
          service: climate.set_temperature
          target:
            entity_id: climate.spa
          data:
            temperature: 32
            hvac_mode: heat
        name: '32'
      - show_name: true
        show_icon: false
        type: button
        tap_action:
          action: call-service
          service: climate.set_temperature
          target:
            entity_id: climate.spa
          data:
            temperature: 35
            hvac_mode: heat
        name: '35'
      - show_name: true
        show_icon: false
        type: button
        tap_action:
          action: call-service
          service: climate.set_temperature
          target:
            entity_id: climate.spa
          data:
            temperature: 36
            hvac_mode: heat
        name: '36'
      - show_name: false
        show_icon: true
        type: button
        tap_action:
          action: call-service
          service: input_number.increment
          target:
            entity_id: input_number.spa_target_temperature
          data: {}
        show_state: false
        icon: mdi:thermometer-plus
        hold_action:
          action: none
  - type: horizontal-stack
    cards:
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: toggle
        entity: switch.spa_bubbles
        name: Bubbles
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: toggle
        entity: switch.spa_filter
        name: Filter
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: toggle
        entity: switch.spa_sanitizer
        name: Sanitizer
        hold_action:
          action: more-info
  - type: vertical-stack
    cards:
      - type: custom:layout-card
        layout_type: custom:grid-layout
        cards:
          - type: conditional
            conditions:
              - entity: input_boolean.spa_in_use
                state: 'off'
            card:
              type: custom:button-card
              entity: input_boolean.spa_in_use
              show_name: true
              show_icon: true
              show_state: false
              name: Not in use
              tap_action: none
              enabled: false
              styles:
                icon:
                  - color: var(--state-icon-color)
              view_layout:
                - header
          - type: conditional
            conditions:
              - entity: input_boolean.spa_in_use
                state: 'on'
            card:
              type: custom:button-card
              entity: input_boolean.spa_in_use
              show_name: true
              show_icon: true
              show_state: false
              name: In use
              styles:
                icon:
                  - color: var(--state-active-color)
              view_layout:
                - header
          - type: markdown
            content: >-
              <table> <tr><td> Last Use Started: </td> <td> {{
              states.input_datetime.spa_in_use_start_time.attributes.timestamp |
              timestamp_custom('%a %d %B %H:%M:%S') }} </td></tr> <tr><td> In
              Use changed: </td> <td> {{
              relative_time(states.input_boolean.spa_in_use.last_updated) }} ago
              </td> </tr>       </table>
            view_layout:
              - main
        layout:
          grid-template-areas: |
            "header main"
          column_widths: auto
          margin: '-4px'
          padding: 0px
          card_margin: 0px
        view_layout:
          card_margin: 0px 0px 0px 0px
          margin: 0px 0px 0px 0px
      - type: markdown
        content: |-
          {% if is_state('climate.spa', 'off') %}
            <font color="#EE3311"><ha-icon icon="mdi:alert"></ha-icon> ! HEATING IS OFF ! </font>
          {% elif not is_state('sensor.spa_error', 'none') %}
            {{ states('sensor.spa_error') }}
            {{ states('sensor.spa_error_description') }}
          {% else %}
            <font color="Green"><ha-icon icon="mdi:check-decagram"></ha-icon> OK </font>
          {% endif %}
        title: Status

Update: added check for HVAC off state, heating should always be on

FreezyExp commented 1 year ago

image

mathieu-mp commented 1 year ago

Hi @FreezyExp,

Thank you for your suggestion.

As you found out, the target temperature info is already available as an attribute of the climate entity, and can be exposed as a status via a template. To ease the user-side automation, I will add the target temperature as a sensor, while making it disabled by default (similar to current temperature sensor).

About the binary is_connected sensor, I am unsure whether the integration is responsible for identifying the connectivity state of the device it interfaces with. Moreover, the spa remote controller could be reachable while it cannot reach the spa itself. Defining the sensor you suggest would need to be very explicit to the user concerning what the connection state covers. I will check if there is something about it in the integration developers documentation, and see what I should do. Meanwhile, you can check for the error code diagnostic sensor, which would be none if the remote control is reachable and it reaches the spa itself, and else would be unavailable or a specific error code.

Regards, Mathieu.

FreezyExp commented 1 year ago

The error code will indicate if the display cannot connect to the base station, where a "wifi connected" could provide a status for the integration to indicate whether the device is online?

I'm not sure what happens at the moment, if there already is some kind of status for the "could not reach over wifi" state then my request for such a status is pointless.

mathieu-mp commented 1 year ago

At the moment, if the spa remote controller is not reachable via wifi, all status are set to "unavailable".

FreezyExp commented 1 year ago

Yes I checked and saw unavailable as expected, this works for automating warning notifications :D

I've updated my status block with a warning should the heating ever be off.

mathieu-mp commented 1 year ago

Implemented by #59