Having Hozelock cloud controller kit intergration

Thanks @FloSyno
I don’t do much with Hozelock in my Home Assistant setup, but here is what it looks like:

###############################################################################
# CONFIGURATION
###############################################################################
sensor:
  - platform: rest
    resource: !secret hozelock_controller_0_url
    name: "Hozelock Controller 0"
    timeout: 60
    value_template: '{{ value_json["controller"]["name"] }}'
    json_attributes:
      - controller
  - platform: template
    sensors:
      hozelock_controller_0_pause_starttime:
        friendly_name: "Début pause"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['pause'] %}
            {{ ( state_attr("sensor.hozelock_controller_0", "controller")["pause"]["startTime"] | int / 1000 ) | int | timestamp_local }}
          {% else %}
            unknown
          {% endif %}
      hozelock_controller_0_pause_endtime:
        friendly_name: "Fin pause"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['pause'] %}
            {{ ( state_attr("sensor.hozelock_controller_0", "controller")["pause"]["endTime"] | int / 1000 ) | int | timestamp_local }}
          {% else %}
            unknown
          {% endif %}
      hozelock_controller_0_pause_duration:
        friendly_name: "Durée pause"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['pause'] %}
            {{ state_attr("sensor.hozelock_controller_0", "controller")["pause"]["duration"] | int / 86400000 | int }}
          {% else %}
            unknown
          {% endif %}
        unit_of_measurement: 'j'

      hozelock_controller_0_adjustment_starttime:
        friendly_name: "Début ajustement"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['adjustment'] %}
            {{ ( state_attr("sensor.hozelock_controller_0", "controller")["adjustment"]["startTime"] | int / 1000 ) | int | timestamp_local }}
          {% else %}
            unknown
          {% endif %}
      hozelock_controller_0_adjustment_endtime:
        friendly_name: "Fin ajustement"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['adjustment'] %}
            {{ ( state_attr("sensor.hozelock_controller_0", "controller")["adjustment"]["endTime"] | int / 1000 ) | int | timestamp_local }}
          {% else %}
            unknown
          {% endif %}
      hozelock_controller_0_adjustment_wateringadjustment:
        friendly_name: "Quantité ajustement"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['adjustment'] %}
            {{ state_attr("sensor.hozelock_controller_0", "controller")["adjustment"]["wateringAdjustment"] }}
          {% else %}
            unknown
          {% endif %}
        unit_of_measurement: '%'
        
      hozelock_controller_0_waternowevent_starttime:
        friendly_name: "Arrosage manuel (début)"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['waterNowEvent'] %}
            {{ ( state_attr("sensor.hozelock_controller_0", "controller")["waterNowEvent"]["startTime"] | int / 1000 ) | int | timestamp_local }}
          {% else %}
            unknown
          {% endif %}
      hozelock_controller_0_waternowevent_endtime:
        friendly_name: "Arrosage manuel (fin)"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['waterNowEvent'] %}
            {{ ( state_attr("sensor.hozelock_controller_0", "controller")["waterNowEvent"]["endTime"] | int / 1000 ) | int | timestamp_local }}
          {% else %}
            unknown
          {% endif %}
      hozelock_controller_0_waternowevent_duration:
        friendly_name: "Arrosage manuel (durée)"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['waterNowEvent'] %}
            {{ state_attr("sensor.hozelock_controller_0", "controller")["waterNowEvent"]["duration"] | int / 60000 | int }}
          {% else %}
            unknown
          {% endif %}
        unit_of_measurement: 'min'
        
      hozelock_controller_0_currentwateringevent_starttime:
        friendly_name: "Arrosage en cours (début)"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['currentWateringEvent'] %}
            {{ ( state_attr("sensor.hozelock_controller_0", "controller")["currentWateringEvent"]["startTime"] | int / 1000 ) | int | timestamp_local }}
          {% else %}
            unknown
          {% endif %}
      hozelock_controller_0_currentwateringevent_endtime:
        friendly_name: "Arrosage en cours (fin)"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['currentWateringEvent'] %}
            {{ ( state_attr("sensor.hozelock_controller_0", "controller")["currentWateringEvent"]["endTime"] | int / 1000 ) | int | timestamp_local }}
          {% else %}
            unknown
          {% endif %}
      hozelock_controller_0_currentwateringevent_duration:
        friendly_name: "Arrosage en cours (durée)"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['currentWateringEvent'] %}
            {{ state_attr("sensor.hozelock_controller_0", "controller")["currentWateringEvent"]["duration"] | int / 60000 | int }}
          {% else %}
            unknown
          {% endif %}
        unit_of_measurement: 'min'
        
      hozelock_controller_0_nextwateringevent_starttime:
        friendly_name: "Prochain arrosage (début)"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['nextWateringEvent'] %}
            {{ ( state_attr("sensor.hozelock_controller_0", "controller")["nextWateringEvent"]["startTime"] | int / 1000 ) | int | timestamp_local }}
          {% else %}
            unknown
          {% endif %}
      hozelock_controller_0_nextwateringevent_endtime:
        friendly_name: "Prochain arrosage (fin)"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['nextWateringEvent'] %}
            {{ ( state_attr("sensor.hozelock_controller_0", "controller")["nextWateringEvent"]["endTime"] | int / 1000 ) | int | timestamp_local }}
          {% else %}
            unknown
          {% endif %}
      hozelock_controller_0_nextwateringevent_duration:
        friendly_name: "Prochain arrosage (durée)"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['nextWateringEvent'] %}
            {{ state_attr("sensor.hozelock_controller_0", "controller")["nextWateringEvent"]["duration"] | int / 60000 | int }}
          {% else %}
            unknown
          {% endif %}
        unit_of_measurement: 'min'

      hozelock_controller_0_lastcommunicationwithserver:
        friendly_name: "Dernière communication"
        value_template: '{{ ( state_attr("sensor.hozelock_controller_0", "controller")["lastCommunicationWithServer"] | int / 1000 ) | int | timestamp_local }}'
      hozelock_controller_0_nextcommunicationwithserver:
        friendly_name: "Prochaine communication"
        value_template: '{{ ( state_attr("sensor.hozelock_controller_0", "controller")["nextCommunicationWithServer"] | int / 1000 ) | int | timestamp_local }}'
      hozelock_controller_0_batterystatus:
        friendly_name: "Etat batterie"
        value_template: '{{ state_attr("sensor.hozelock_controller_0", "controller")["batteryStatus"] }}'
      hozelock_controller_0_signalstrength:
        friendly_name: "Puissance signal"
        value_template: '{{ state_attr("sensor.hozelock_controller_0", "controller")["signalStrength"] }}'
      hozelock_controller_0_overridescheduleduration:
        friendly_name: "Remplacement durée prog"
        value_template: >-
          {% if states.sensor.hozelock_controller_0.attributes.controller['overrideScheduleDuration'] %}
            {{ state_attr("sensor.hozelock_controller_0", "controller")["overrideScheduleDuration"] | int / 60000 | int }}
          {% else %}
            unknown
          {% endif %}
        unit_of_measurement: 'min'

      hozelock_controller_0_schedulename:
        friendly_name: "Nom programme"
        value_template: '{{ state_attr("sensor.hozelock_controller_0", "controller")["schedule"]["name"] }}'

rest_command:
# Hozelock
  hozelock_waternow:
    url: https://hoz3.com/restful/support/hubs/{{ hub_id }}/controllers/actions/waterNow
    method: POST
    payload: '{"controllerIDs":[ {{ controller_id }} ],"duration": {{ duration }} }'
    content_type:  'application/json'
  hozelock_stopwatering:
    url: https://hoz3.com/restful/support/hubs/{{ hub_id }}/controllers/actions/stopWatering
    method: POST
    payload: '{"controllerIDs":[ {{ controller_id }} ]}'
    content_type:  'application/json'
  hozelock_pause:
    url: https://hoz3.com/restful/support/hubs/{{ hub_id }}/controllers/actions/pause
    method: POST
    payload: '{"controllerIDs":[ {{ controller_id }} ],"duration": {{ duration }} }'
    content_type:  'application/json'
  hozelock_unpause:
    url: https://hoz3.com/restful/support/hubs/{{ hub_id }}/controllers/actions/unpause
    method: POST
    payload: '{"controllerIDs":[ {{ controller_id }} ]}'
    content_type:  'application/json'

input_number:
  hozelock_duration:
    name: Durée
    min: 1
    max: 60
    step: 1
    icon: mdi:clock-outline
    unit_of_measurement: "min"
  hozelock_duration_pause:
    name: Durée
    min: 1
    max: 14
    step: 1
    icon: mdi:clock-outline
    unit_of_measurement: "j"

binary_sensor:
  - platform: template
    sensors:
      hozelock_controller_0_haswaternowevent:
        friendly_name: "Water now event"
        value_template: '{{ state_attr("sensor.hozelock_controller_0", "controller")["hasWaterNowEvent"] }}'
      hozelock_controller_0_ischildlockenabled:
        friendly_name: "Verrou enfant"
        value_template: '{{ state_attr("sensor.hozelock_controller_0", "controller")["isChildlockEnabled"] }}'
      hozelock_controller_0_iswatering:
        friendly_name: "Arrosage en cours"
        value_template: '{{ state_attr("sensor.hozelock_controller_0", "controller")["isWatering"] }}'
      hozelock_controller_0_ispanelremoved:
        friendly_name: "Panneau retiré"
        value_template: '{{ state_attr("sensor.hozelock_controller_0", "controller")["isPanelRemoved"] }}'
      hozelock_controller_0_isadjusted:
        friendly_name: "Ajustement"
        value_template: '{{ state_attr("sensor.hozelock_controller_0", "controller")["isAdjusted"] }}'
      hozelock_controller_0_isscheduleuptodate:
        friendly_name: "Calendrier à jour"
        value_template: '{{ state_attr("sensor.hozelock_controller_0", "controller")["isScheduleUpToDate"] }}'
      hozelock_controller_0_ispaused:
        friendly_name: "En pause"
        value_template: '{{ state_attr("sensor.hozelock_controller_0", "controller")["isPaused"] }}'
      hozelock_controller_0_nextwateringevent_enabled:
        friendly_name: "Prochain arrosage activé"
        value_template: '{{ state_attr("sensor.hozelock_controller_0", "controller")["nextWateringEvent"]["enabled"] }}'
      hozelock_controller_0_currentwateringevent_enabled:
        friendly_name: "Arrosage en cours activé"
        value_template: '{{ state_attr("sensor.hozelock_controller_0", "controller")["currentWateringEvent"]["enabled"] }}'

###############################################################################
# AUTOMATIONS
###############################################################################
automation:
  - id: notification_debut_arrosage
    alias: Notification début d'arrosage
    trigger:
      - platform: state
        entity_id: binary_sensor.hozelock_controller_0_iswatering
        to: 'on'
    action:
      - delay: '00:00:10'
      - service: persistent_notification.create
        data_template:
          title: Hozelock
          message: "{{ states('sensor.hozelock_controller_0_currentwateringevent_starttime') }}: début d'arrosage pour une durée de {{ states('sensor.hozelock_controller_0_currentwateringevent_duration') }} min"

###############################################################################
# SCRIPTS
###############################################################################
script:
  # Hozelock
  hozelock_waternow:
    alias: Démarrer arrosage manuel
    sequence:
      - service: rest_command.hozelock_waternow
        data_template:
          hub_id: !secret hozelock_hub_id
          controller_id: 0
          duration: "{{ states('input_number.hozelock_duration') | int * 60000 }}"
  hozelock_stopwatering:
    alias: Arrêter arrosage manuel
    sequence:
      - service: rest_command.hozelock_stopwatering
        data_template:
          hub_id: !secret hozelock_hub_id
          controller_id: 0
  hozelock_pause:
    alias: Suspendre arrosage
    sequence:
      - service: rest_command.hozelock_pause
        data_template:
          hub_id: !secret hozelock_hub_id
          controller_id: 0
          duration: "{{ states('input_number.hozelock_duration_pause') }}"
  hozelock_unpause:
    alias: Reprise arrosage
    sequence:
      - service: rest_command.hozelock_unpause
        data_template:
          hub_id: !secret hozelock_hub_id
          controller_id: 0


And the UI:

I’m sure someone else could do better :smile:

1 Like

Hi guys. I’m new to this GitHub thing. I bought this hozelock cloud controller for one reason and one reason only. That is to turn water on and turn water off. It looks like I can’t do this instantly. I’m not using it to water my plants. I just need to switch water on and off remotely. Is there a way to do this?

Thanks for sharing the API documentation in GitHub. I found that the duration units for pause and adjust actions to be incorrect.

Both should be days rather than milliseconds. I coud not raise an issue in GitHub so posting here instead.

Thanks for the input. I have changed this in the Repo. Not sure why it wouldn’t let you raise an issue or a PR.

1 Like

Building upon the previous posts I am sharing my YAML configuration. I’ve made a few corrections and improvements to the above examples, please feel welcome to reuse. Remember to replace “123ABC” with your unique hub ID.

/config/configuration.yaml

sensor: !include sensors.yaml
rest_command: !include rest_command.yaml
template: !include templates.yaml

/config/sensors.yaml

##########################################
### Hozelock Sensors #####################
##########################################
# Hozelock hub status
- platform: rest
  name: Hozelock Hub Status
  resource: https://hoz3.com/restful/support/hubs/123ABC/
  verify_ssl: false
  method: GET
  value_template: '{{ value_json["hub"]["name"] }}'
  json_attributes:
    - hub
  scan_interval: 60

# Hozelock controller status
- platform: rest
  name: Hozelock Controller Status
  resource: https://hoz3.com/restful/support/hubs/123ABC/controllers/0
  verify_ssl: false
  method: GET
  value_template: '{{ value_json["controller"]["name"] }}'
  json_attributes:
    - controller
  scan_interval: 60

/config/rest_command.yaml

##########################################
### Hozelock Commands ####################
##########################################
# Hozelock hub water irrigation control
hozelock_water_now:
  url: "https://hoz3.com/restful/support/hubs/123ABC/controllers/actions/waterNow"
  method: POST
  payload: '{"controllerIDs":[0],"duration":600000}' # 10 mins
  content_type: 'application/json'
  verify_ssl: false

hozelock_stop_watering:
  url: "https://hoz3.com/restful/support/hubs/123ABC/controllers/actions/stopWatering"
  method: POST
  payload: '{"controllerIDs":[0]}'
  content_type: 'application/json'
  verify_ssl: false

hozelock_pause:
  url: "https://hoz3.com/restful/support/hubs/123ABC/controllers/actions/pause"
  method: POST
  payload: '{"controllerIDs":[0],"duration":{{ states("input_number.hozelock_pause_duration") }} }'
  content_type: 'application/json'
  verify_ssl: false

hozelock_unpause:
  url: "https://hoz3.com/restful/support/hubs/123ABC/controllers/actions/unpause"
  method: POST
  payload: '{"controllerIDs":[0]}'
  content_type: 'application/json'
  verify_ssl: false

hozelock_adjust:
  url: "https://hoz3.com/restful/support/hubs/123ABC/controllers/actions/adjust"
  method: POST
  payload: '{"controllerIDs":[0],"duration":{{ states("input_number.hozelock_adjustment_duration") }},"wateringAdjustment":{{ states("input_number.hozelock_adjustment_change") }} }'
  content_type: 'application/json'
  verify_ssl: false

hozelock_unadjust:
  url: "https://hoz3.com/restful/support/hubs/123ABC/controllers/actions/unadjust"
  method: POST
  payload: '{"controllerIDs":[0]}'
  content_type: 'application/json'
  verify_ssl: false
  

/config/templates.yaml

- sensor:

##########################################
### Hozelock Status ######################
##########################################
# Watering now
  - name: "Hozelock Watering Now"
    unique_id: hozelock_watering_now
    state: "{{ state_attr('sensor.hozelock_controller_status', 'controller')['isWatering'] }}"
# Watering paused
  - name: "Hozelock Watering Paused"
    unique_id: hozelock_watering_paused
    state: "{{ state_attr('sensor.hozelock_controller_status', 'controller')['isPaused'] }}"
# Watering adjusted
  - name: "Hozelock Watering Adjusted"
    unique_id: hozelock_watering_adjusted
    state: "{{ state_attr('sensor.hozelock_controller_status', 'controller')['isAdjusted'] }}"
# Battery status
  - name: "Hozelock Battery Status"
    unique_id: hozelock_battery_status
    state: "{{ state_attr('sensor.hozelock_controller_status', 'controller')['batteryStatus'] }}"
# Signal strength
  - name: "Hozelock Signal Strength"
    unique_id: hozelock_signal_strength
    state: "{{ state_attr('sensor.hozelock_controller_status', 'controller')['signalStrength'] }}"
# Uresponsive
  - name: "Hozelock Uresponsive"
    unique_id: hozelock_Uresponsive
    state: "{{ state_attr('sensor.hozelock_hub_status', 'hub')['isUresponsive'] }}"
# Last server contact
  - name: "Hozelock Server Last Poll"
    unique_id: hozelock_server_last_poll
    state: "{{ as_timestamp((state_attr('sensor.hozelock_hub_status', 'hub')['lastServerContactDate'] | int / 1000) | as_datetime) | timestamp_custom('%a %d/%b %-H:%M') }}"

##########################################
### Hozelock Schedule ####################
##########################################
# Water start
  - name: "Hozelock Water Start"
    unique_id: hozelock_water_start
    state: >-
      {% if (state_attr('sensor.hozelock_controller_status', 'controller')['nextWateringEvent'] is none ) %} NA
      {% else %} {{ as_timestamp((state_attr('sensor.hozelock_controller_status', 'controller')['nextWateringEvent']['startTime'] | int / 1000) | as_datetime) | timestamp_custom('%a %d/%b %-H:%M') }}
      {% endif %}    
# Water end
  - name: "Hozelock Water End"
    unique_id: hozelock_water_end
    state: >-
      {% if (state_attr('sensor.hozelock_controller_status', 'controller')['nextWateringEvent'] is none ) %} NA
      {% else %} {{ as_timestamp((state_attr('sensor.hozelock_controller_status', 'controller')['nextWateringEvent']['endTime'] | int / 1000) | as_datetime) | timestamp_custom('%a %d/%b %-H:%M') }}
      {% endif %}    
# Water duration
  - name: "Hozelock Water Duration"
    unique_id: hozelock_water_duration
    state: >-
      {% if (state_attr('sensor.hozelock_controller_status', 'controller')['nextWateringEvent'] is none ) %} NA
      {% else %} {{ (state_attr('sensor.hozelock_controller_status', 'controller')['nextWateringEvent']['duration'] | int / 60000) | int }} mins
      {% endif %}    

##########################################
### Hozelock Pause #######################
##########################################
# Pause start
  - name: "Hozelock Pause Start"
    unique_id: hozelock_pause_start
    state: >-
      {% if (state_attr('sensor.hozelock_controller_status', 'controller')['pause'] is none ) %} NA
      {% else %} {{ as_timestamp((state_attr('sensor.hozelock_controller_status', 'controller')['pause']['startTime'] | int / 1000) | as_datetime) | timestamp_custom('%a %d/%b %-H:%M') }}
      {% endif %}
# Pause end
  - name: "Hozelock Pause End"
    unique_id: hozelock_pause_end
    state: >-
      {% if (state_attr('sensor.hozelock_controller_status', 'controller')['pause'] is none ) %} NA
      {% else %} {{ as_timestamp((state_attr('sensor.hozelock_controller_status', 'controller')['pause']['endTime'] | int / 1000) | as_datetime) | timestamp_custom('%a %d/%b %-H:%M') }}
      {% endif %}
# Pause duration
  - name: "Hozelock Pause Duration"
    unique_id: hozelock_pause_duration
    state: >-
      {% if (state_attr('sensor.hozelock_controller_status', 'controller')['pause'] is none ) %} NA
      {% else %} {{ (state_attr('sensor.hozelock_controller_status', 'controller')['pause']['duration'] | int / 86400000) | int }} days
      {% endif %}

##########################################
### Hozelock Adjust ######################
##########################################
# Adjust start
  - name: "Hozelock Adjustment Start"
    unique_id: hozelock_adjustment_start
    state: >-
      {% if (state_attr('sensor.hozelock_controller_status', 'controller')['adjustment'] is none ) %} NA
      {% else %} {{ as_timestamp((state_attr('sensor.hozelock_controller_status', 'controller')['adjustment']['startTime'] | int / 1000) | as_datetime) | timestamp_custom('%a %d/%b %-H:%M') }}
      {% endif %}
# Adjust end
  - name: "Hozelock Adjustment End"
    unique_id: hozelock_adjustment_end
    state: >-
      {% if (state_attr('sensor.hozelock_controller_status', 'controller')['adjustment'] is none ) %} NA
      {% else %} {{ as_timestamp((state_attr('sensor.hozelock_controller_status', 'controller')['adjustment']['endTime'] | int / 1000) | as_datetime) | timestamp_custom('%a %d/%b %-H:%M') }}
      {% endif %}
# Adjust duration
  - name: "Hozelock Adjustment Change"
    unique_id: hozelock_adjustment_change
    state: >-
      {% if (state_attr('sensor.hozelock_controller_status', 'controller')['adjustment'] is none ) %} NA
      {% else %} {{ state_attr('sensor.hozelock_controller_status', 'controller')['adjustment']['wateringAdjustment'] }}%
      {% endif %}
# Adjust duration
  - name: "Hozelock Adjustment Duration"
    unique_id: hozelock_adjustment_duration
    state: >-
      {% if (state_attr('sensor.hozelock_controller_status', 'controller')['adjustment'] is none ) %} NA
      {% else %} {{ (state_attr('sensor.hozelock_controller_status', 'controller')['adjustment']['duration'] | int / 86400000) | int }} days
      {% endif %}

Configure helpers through the UI or add them manually using the below text.
…\config\.storage\input_number

{
  "version": 1,
  "minor_version": 1,
  "key": "input_number",
  "data": {
    "items": [
      {
        "id": "hozelock_pause_duration",
        "min": 1.0,
        "max": 355.0,
        "name": "Hozelock Pause Duration",
        "mode": "box",
        "step": 1.0,
        "unit_of_measurement": "Days",
        "icon": "mdi:clock-time-eight-outline"
      },
      {
        "id": "hozelock_adjustment_duration",
        "min": 1.0,
        "max": 14.0,
        "name": "Hozelock Adjustment Duration",
        "mode": "box",
        "step": 1.0,
        "unit_of_measurement": "Days",
        "icon": "mdi:clock-time-eight-outline"
      },
      {
        "id": "hozelock_adjustment_change",
        "min": -100.0,
        "max": 100.0,
        "name": "Hozelock Adjustment Change",
        "step": 25.0,
        "mode": "box",
        "unit_of_measurement": "%",
        "icon": "mdi:water-percent"
      }
    ]
  }
}

and here is my simple Lovelace design for the above YAML configuration.

Simply copy and paste below text into the “raw configuration editor” into a new dashboard.

views:
  - title: Hozelock
    badges: []
    cards:
      - type: entities
        entities:
          - entity: sensor.hozelock_water_start
            icon: mdi:calendar
          - entity: sensor.hozelock_water_end
            icon: mdi:calendar
          - entity: sensor.hozelock_water_duration
            icon: mdi:calendar
          - entity: sensor.hozelock_pause_start
            icon: mdi:calendar
          - entity: sensor.hozelock_pause_end
            icon: mdi:calendar
          - entity: sensor.hozelock_pause_duration
            icon: mdi:calendar
          - entity: sensor.hozelock_adjustment_start
            icon: mdi:calendar
          - entity: sensor.hozelock_adjustment_end
            icon: mdi:calendar
          - entity: sensor.hozelock_adjustment_duration
            icon: mdi:calendar
          - entity: sensor.hozelock_adjustment_change
            icon: mdi:calendar
        title: Watering Schedule
      - type: entities
        entities:
          - entity: sensor.hozelock_watering_now
            icon: mdi:watering-can
          - entity: sensor.hozelock_watering_paused
            icon: mdi:watering-can
          - entity: sensor.hozelock_watering_adjusted
            icon: mdi:watering-can
          - entity: sensor.hozelock_battery_status
            icon: mdi:battery-charging
          - entity: sensor.hozelock_signal_strength
            icon: mdi:wifi-strength-2
          - entity: sensor.hozelock_uresponsive
            icon: mdi:wan
          - entity: sensor.hozelock_server_last_poll
            icon: mdi:wan
        title: Watering Status
      - title: Watering Control
        square: false
        type: grid
        cards:
          - show_name: true
            show_icon: false
            type: button
            tap_action:
              action: call-service
              service: rest_command.hozelock_water_now
              target: {}
            entity: sensor.hozelock_hub_status
            name: Water Now
          - show_name: true
            show_icon: false
            type: button
            tap_action:
              action: call-service
              service: rest_command.hozelock_stop_watering
              target: {}
            entity: sensor.hozelock_hub_status
            name: Stop Watering
          - show_name: true
            show_icon: false
            type: button
            tap_action:
              action: call-service
              service: rest_command.hozelock_pause
              target: {}
            entity: sensor.hozelock_hub_status
            name: Pause Schedule
          - show_name: true
            show_icon: false
            type: button
            tap_action:
              action: call-service
              service: rest_command.hozelock_unpause
              target: {}
            entity: sensor.hozelock_hub_status
            name: Remove Pause
          - show_name: true
            show_icon: false
            type: button
            tap_action:
              action: call-service
              service: rest_command.hozelock_adjust
              target: {}
            entity: sensor.hozelock_hub_status
            name: Adjust Duration
          - show_name: true
            show_icon: false
            type: button
            tap_action:
              action: call-service
              service: rest_command.hozelock_unadjust
              target: {}
            entity: sensor.hozelock_hub_status
            name: Remove Adjustment
        columns: 2
      - type: entities
        entities:
          - entity: input_number.hozelock_pause_duration
          - entity: input_number.hozelock_adjustment_duration
          - entity: input_number.hozelock_adjustment_change
        title: Watering Override
title: Hozelock

I made a simple Hozelock card using Button-Card , Stack-in-Card and Card-Mod for those interested

image

and here is the yaml

type: custom:stack-in-card
title: Watering
mode: vertical
box_shadow: false
cards:
  - type: custom:stack-in-card
    mode: horizontal
    box_shadow: false
    card_mod:
      style: |
        ha-card { border: none; box-shadow: none; }
    cards:
      - type: custom:button-card
        entity: sensor.hozelock_watering
        show_name: false
        show_state: false
        show_label: false
        name: Watering
        size: 100%
        color_type: auto
        icon: mdi:watering-can
        card_mod:
          style: |
            ha-card { border: none; box-shadow: none; }
        state:
          - value: 'True'
            styles:
              icon:
                - color: var(--paper-item-icon-active-color)
          - value: 'False'
            styles:
              icon:
                - color: var(--paper-item-icon-color)
        styles:
          icon:
            - color: steelblue
          card:
            - height: 185px
            - padding: 5px
      - type: custom:stack-in-card
        mode: vertical
        box_shadow: false
        card_mod:
          style: |
            ha-card { border: none; box-shadow: none; }        
        cards:
          - type: custom:button-card
            entity: sensor.hozelock_water_start
            name: Start
            show_icon: false
            show_state: true
            layout: name_state
            tooltip: Schedule start time
            card_mod:
              style: |
                ha-card { border: none; box-shadow: none; }
            styles:
              card:
                - height: 35px
                - width: 180px
                - padding: 5px 0px 5px 0px
                - margin-top: 40px
              name:
                - white-space: nowrap
                - overflow: hidden
                - text-overflow: clip
                - justify-self: start
          - type: custom:button-card
            entity: sensor.hozelock_water_end
            name: End
            show_icon: false
            show_state: true
            layout: name_state
            tooltip: Schedule end time
            card_mod:
              style: |
                ha-card { border: none; box-shadow: none; }
            styles:
              card:
                - height: 35px
                - width: 180px
                - padding: 5px 0px 5px 0px
              name:
                - white-space: nowrap
                - overflow: hidden
                - text-overflow: clip
                - justify-self: start
          - type: custom:button-card
            entity: sensor.hozelock_water_duration
            name: Duration
            show_icon: false
            show_state: true
            layout: name_state
            tooltip: Schedule duration
            card_mod:
              style: |
                ha-card { border: none; box-shadow: none; }
            styles:
              card:
                - height: 35px
                - width: 180px
                - padding: 5px 0px 5px 0px
              name:
                - white-space: nowrap
                - overflow: hidden
                - text-overflow: clip
                - justify-self: start
  - type: custom:stack-in-card
    mode: horizontal
    box_shadow: false
    card_mod:
      style: |
        ha-card { border: none; box-shadow: none; }
    cards:
      - type: conditional
        conditions:
          - entity: sensor.hozelock_watering_now
            state: 'False'
        card:
          type: custom:button-card
          color: auto
          icon: mdi:water-plus
          name: Water Now
          size: 100%
          tooltip: Water Now
          styles:
            icon:
              - color: steelblue
            card:
              - height: 110px
              - padding: 15px 0px 15px 0px
            name:
              - white-space: nowrap
              - overflow: hidden
              - text-overflow: clip
          tap_action:
            action: call-service
            service: rest_command.hozelock_water_now
            target: {}
      - type: conditional
        conditions:
          - entity: sensor.hozelock_watering_now
            state: 'True'
        card:
          type: custom:button-card
          color: auto
          icon: mdi:water-minus
          name: Stop Watering
          size: 100%
          tooltip: Stop Watering
          styles:
            icon:
              - color: steelblue
            card:
              - height: 110px
              - padding: 15px 0px 15px 0px
            name:
              - white-space: nowrap
              - overflow: hidden
              - text-overflow: clip
          tap_action:
            action: call-service
            service: rest_command.hozelock_stop_watering
            target: {}
      - type: conditional
        conditions:
          - entity: sensor.hozelock_watering_adjusted
            state: 'False'
        card:
          type: custom:button-card
          color: auto
          icon: mdi:weather-sunny
          name: Adjust
          size: 100%
          tooltip: Adjust Watering
          styles:
            icon:
              - color: steelblue
            card:
              - height: 110px
              - padding: 15px 0px 15px 0px
            name:
              - white-space: nowrap
              - overflow: hidden
              - text-overflow: clip
          tap_action:
            action: call-service
            service: rest_command.hozelock_adjust
            target: {}
      - type: conditional
        conditions:
          - entity: sensor.hozelock_watering_adjusted
            state: 'True'
        card:
          type: custom:button-card
          color: auto
          icon: mdi:weather-rainy
          name: Remove Adjust
          size: 100%
          tooltip: Remove Adjustment
          styles:
            icon:
              - color: steelblue
            card:
              - height: 110px
              - padding: 15px 0px 15px 0px
            name:
              - white-space: nowrap
              - overflow: hidden
              - text-overflow: clip
          tap_action:
            action: call-service
            service: rest_command.hozelock_unadjust
            target: {}
      - type: conditional
        conditions:
          - entity: sensor.hozelock_watering_paused
            state: 'False'
        card:
          type: custom:button-card
          color: auto
          icon: mdi:calendar-month-outline
          name: Pause
          size: 100%
          tooltip: Pause Watering
          styles:
            icon:
              - color: steelblue
            card:
              - height: 110px
              - padding: 15px 0px 15px 0px
            name:
              - white-space: nowrap
              - overflow: hidden
              - text-overflow: clip
          tap_action:
            action: call-service
            service: rest_command.hozelock_pause
            target: {}
      - type: conditional
        conditions:
          - entity: sensor.hozelock_watering_paused
            state: 'True'
        card:
          type: custom:button-card
          color: auto
          icon: mdi:calendar-remove-outline
          name: Remove Pause
          size: 100%
          tooltip: Remove Pause
          styles:
            icon:
              - color: steelblue
            card:
              - height: 110px
              - padding: 15px 0px 15px 0px
            name:
              - white-space: nowrap
              - overflow: hidden
              - text-overflow: clip
          tap_action:
            action: call-service
            service: rest_command.hozelock_unpause
            target: {}

Hello there, I have just got the hozelock cloud controller and I am going to use your code.
Any tips?

How long of a time dely do you get.