Can you elaborate? Is this a real integration? I think it would be useful service call for those integrations that do not retry automatically.
The guide for getting the secret key does not work. I think it needs to be updated. Maybe a guide to sniff it out
Sure, the github is here: Retry
Iâm currently using it like this:
action: retry.actions
metadata: {}
data:
retries: 5
backoff: "[[ 15 * 2 ** attempt ]]"
validation: >-
[[ state_attr(entity_id, 'temperature') == temperature and
is_state(entity_id, hvac_mode) ]]
state_delay: 5
repair: true
retry_id: "climate.wiser_livingroom_hvac_temperature"
sequence:
- action: climate.set_temperature
target:
entity_id: climate.wiser_livingroom
data:
temperature: 18
hvac_mode: "heat"
Edited to remove my templates
Thanks for the info.
It retries actions not reloads integrations.
However it looks really interesting and I can think of several use cases for it when I try to reload/reboot devices and sensors.
Your example is informative - cheers
For missed commands, itâs probably the hub having disconnected from WiFi. I solved it with a simple wait template I use as the very first action in automations:
actions:
# Check Wiser Hub is not offline and wait for it to come back online if it is
- wait_template: "{{ is_state('binary_sensor.wiser_hub_status', 'off') and is_state('binary_sensor.wiser_hub', 'on') }}"
Create a Ping binary sensor AND a template binary sensor as follows:
# Wiser Hub Status binary sensor
- name: Wiser Hub Status
unique_id: C091D37C-4A26-48C2-BDA6-94F7B8B5568B
device_class: problem
icon: >-
{%- if is_state('binary_sensor.wiser_hub_status', 'on') -%}
mdi:router-wireless-off
{%- else -%}
mdi:router-wireless
{%- endif -%}
state: >-
{%- if is_state_attr('sensor.wiser_hub_heating_operation_mode', 'last_update_status', 'Success') -%}
off
{%- else -%}
on
{%- endif -%}
Years ago, when the disconnection problems were really frequent, I had automations that acted up until I did this.
If you need to reload an integration use:
- action: homeassistant.reload_config_entry
data:
entry_id: 885ed8abb7ebf3e4cea8627a61061659
The entry_id is found by searching for the integration name in the file:
\config\.storage\.storage\core.config_entries
e.g. I am restarting my Airthings BLE integration when itâs entities are unavailable for a while.
{
"domain": "airthings_ble",
"entry_id": "885ed8abb7ebf3e4cea8627a61061659"
}
Thanks Robert,
I already know that and use it. But retrying an action is something new to me and I think I would find it useful.
Again Thank you reminding me - cheers Mike
Personally I donât use the Retry HACS integration. I installed it years ago thinking I might find a use for it, but Iâve always just created a loop in my automation to check for states, where I need to retry something multiple times.
However, I can see how the Retry integration would be useful for some people.
Both methods are probably equally good options. I just favour the native option personally.
Yeah it wonât re-load the integration automatically but there is an error key in the config. I prefer manual intervention which is why I didnât use it in my example but you could have it fire an action to reload wiser integration when it fails the count of retries.
Relevant part of the README.
on_error parameter (optional)
A sequence of actions to perform if all retries fail.
Here is an automation rule example with a self remediation logic:
alias: Kitchen Evening Lights
mode: parallel
trigger:
- platform: sun
event: sunset
action:
- action: retry.action
data:
action: light.turn_on
entity_id: light.kitchen_light
retries: 2
on_error:
- action: homeassistant.reload_config_entry
data:
entry_id: "{{ config_entry_id(entity_id) }}"
- delay:
seconds: 20
- action: automation.trigger
target:
entity_id: automation.kitchen_evening_lights
Your most welcome as well.
I was using loops the same as robert before but ended up preferring this solution in the end but both solution have the same outcome. I like the repair notices as it gives me some indication if something is starting to fail really bad.
The wait solution is very clean though might have to try that myself.
Hi there,
Iâve been going through my Watchman log for issues with entities. The following two entities related to Drayton Wiser are coming up as unknown:
button.wiser_boost_hot_water
button.wiser_cancel_hot_water_ overrides
Both entities are found - is it just showing as unknown because it doesnât have any data against it (e.g. not used since the entity was created?).
Thanks!
Thanks for sharing.
Inspired by your approach, I set up a hub ping sensor (1 ping every 10s) and discovered it spikes occasionally from <10ms to >100ms. Iâm guessing the spikes are when the hub CPU is struggling.
With this insight, I augmented your health check logic to include ping spikes (>50ms), in a GUI template sensor (name: Wiser API, class: Problem):
{% set ping_ms = states('sensor.wiser_lan_round_trip_time_average') %}
{% set ping_problem = ping_ms in ['unknown', 'unavailable', 'none']
or ping_ms | int(999) > 50 %}
{% set poll_failure = not is_state_attr(
'sensor.wiser_heating_operation_mode',
'last_update_status',
'Success'
) %}
{{ ping_problem or poll_failure }}
With hindsight, my prior Wiser automation fragility was likely due to sending commands while the CPU was overloaded and not waiting for a successful hub poll before evaluating the results.
So I created two guard scripts to wrap around Wiser commands in retry loops: a pre-flight Wiser Wait for Healthy API check (similar to yours), and a post-flight Wiser Wait for Next Successful Poll check.
Here are the scripts if folk are interested.
alias: Wiser Wait for Healthy API
description: >-
Blocking guard script that waits for the Wiser hub to be reachable and healthy.
Wait for a fresh ping if over half way through the 10s ping cycle.
mode: queued
max: 50
sequence:
- wait_template: >
{{ as_timestamp(now()) -
as_timestamp(states.sensor.wiser_lan_round_trip_time_average.last_updated)
<= 5 }}
- wait_template: "{{ is_state('binary_sensor.wiser_api', 'off') }}"
alias: Wiser Wait for Next Successful Poll
mode: parallel
max: 50
sequence:
- variables:
last_poll: "{{ states.sensor.wiser_heating_operation_mode.last_updated }}"
- wait_template: |
{{ states.sensor.wiser_heating_operation_mode.last_updated != last_poll }}
- wait_template: |
{{ is_state_attr(
'sensor.wiser_heating_operation_mode',
'last_update_status',
'Success'
) }}
Thanks again for inspiring me (and to ChatGPT for cranking out code so fast!). Iâll report back in a couple of weeks on how effective this is.
What happens if you press one of them?
I would be careful about overriding the default ping of 30 seconds. IIRC pinging the hub too regularly (Iâm fairly sure this was covered in this thread a few years ago - you would need to search) can cause problems of itâs own and cause disconnects itself by overloading the hub.
My ping sensor is using the default of 30 seconds and sends 2 pings.
I considered that and reasoned a single ping is v low load. Its 2-4ms typical round-trip times seem to validate that.
Where I suspect people went wrong in the past is using the defaults of 5 pings and 180s âConsider home intervalâ, as that hammers the hub repeatedly with 5 closely-spaced workloads and takes 3 minutes to detect a problem.
Whatâs your rationale for 2 closely-spaced pings every 30s instead of spacing them evenly (i.e. 1 every 15s)? The latter should be gentler on the hub and provide more granular telemetry, for the same total pings. Or put another way, what extra value does the second ping provide?
You have misunderstood that Consider home interval is only for the ping device tracker entity, if you enable it, which you donât want for a ping to a hub.
Since the Ping sensor was moved to the UI, it defaults to 30 seconds with the only way of changing that being to create your own automation and disable the Polling for updates setting. This was done intentionally by the developers to stop people pinging things too frequently (especially cloud services) e.g. every 10 seconds. If you havenât created an automation to do that, you are on the default of 30 seconds. Putting 10 in the âconsider home intervalâ does not make it run every 10 seconds, nor does leaving it at 180 make it take 3 minutes to detect a problem. Itâs for the device tracker entity only, to stop the state flapping, which is disabled by default.
Please see the Ping documentation here.
I use two pings for all my ping sensors. The second one is for redundancy to make sure the first one wasnât missed or reported incorrectly.
Youâre right. âConsider home intervalâ is irrelevant for determining hub health. Thanks for correcting me.
Let me clarify my understanding of the other two ping choices, as I wouldnât want others reading this thread to conclude that a 10s ping is risky for a hub.
Background: A single ping is a near-effortless workload, even for a Wiser hub. Itâs 32 bytes of low-compute data. Thatâs 100x smaller than the 3k-10Kb polling response that the hub sends to HA every 30s for a typical home, not to mention the CPU load of crafting the poll response. If a hubâs CPU is severely loaded, a ping request could topple it but itâs an edge-case risk.
In HA, there are 2 Ping settings to consider for detecting Wiser hub health:
-
Ping interval: Default is 30s, with a minimum of 10s (for the reasons @robertwigley explains above). Shorter intervals give fresher hub state telemetry, and the 10s minimum is unlikely to affect the hubâs performance.
-
Ping count is how many 1s-spaced pings are sent in each âintervalâ. Default is 5 pings. Ping count will have more impact on a hub than ping interval, because the 1s spacing gives the CPU less time to recover. Although risk is low given the tiny footprint of a ping.
A more compelling reason to choose a small ping count is responsiveness: if a hub falls offline, a ping sensor takes 4s to detect this condition with the default ping count of 5 ping, whereas a ping count of 1 or 2 reduces the detection delay to 0s or 1s respectively.
Does that sound right, or have I missed something?
On a related note, the stability of my Wiser automations has been transformed by the hub health check scripts I shared above. Hereâs an example of the health sensor detecting when the hub slowed down or fell offline yesterday (âWiser APIâ bar above the graph):
Thanks again @robertwigley for inspiring me to go down this path.
Is it possible to boost/override a room temperature using the REST API, the same as you can from the Wiser app or HA?
I am writing a small python app, which presents HA features on a touch screen. Adding a tab for my Wiser rooms, I can read if the TRV is currently requesting heat, what the current temperature is and what the target temperature is.
I have added a + and - button for each room in an attempt to allow a short term override until the next point in the schedule, but it does not work.
There seems to be two devices available.
"climate.wiser_living_room": {
"entity_id": "climate.wiser_living_room",
"state": "auto",
...output cut...
"attributes": {
"current_temperature": 19.7,
"temperature": 15.0,
and
"sensor.wiser_lts_target_temperature_living_room": {
"entity_id": "sensor.wiser_lts_target_temperature_living_room",
"state": "15.0",
I have tried making a POST request to the REST API at /api/states/<entity_id>, setting the temperature in the attributes for the climate device or the state (converting to string) for the sensor device. Both appear to be successful, returning a 200, but it does not do anything. When the app next polls HA for the Wiser data, it comes back with the previous value. It looks like these two devices may be read only as far as the API is concerned.
Is overriding a temperature a feature? There is a button.wiser_boost_all_heating which I can call for all radiators, but none for individual ones.
You need to use the service call rest api to control things like this.
Thanks, that does look to be the right area. The documentation suggests sending data like this will work:
boostData={ "data": {
"time_period": 60,
"temperature_delta":2
},
"target":{
"entity_id": "climate.wiser_study"
}
}
Is that the right format it is expecting? It doesnât match data I get if I call a get on /api/services.
Python is throwing some errors at that JSON, but I think that is a python thing rather than a HA thing. It can be awkward with nested JSON and POST requests.

