This module implements a water heater Task based on the Aquanta device.
class WaterHeaterState()
Water heater state: temperature and tank level.
The Aquanta sensors are unreliable and sometimes give the false impression that the tank is full and the temperature good while actually the water heater ran for a limited time a obviously isn't full nor has been able to reach this temperature for the water of the entire tank.
This WaterHeaterState class acts as a proxy by updating the state representation
class WaterHeater(Task, Sensor)
Aquanta controlled water heater Task and Sensor.
This task makes use of the Aquanta away and boost features to control the water heater.
The implementation assumes that the Aquanta device is configured in timer mode. As a result, the code is a little bit complexity to handle the schedules but the benefit is that if the task/scheduler stops running, or if the Aquanta server is inaccessible or, if the API changed unexpectedly, the Aquanta device should fallback automatically on its schedule.
The Aquanta temperature sensor and available water are per design partially driven by some software algorithms. Indeed the temperature sensor sit outside the tank and the water level cannot be detected accurately. Therefore, if the water heater is not using any power for a little while, the WaterHeater task stops itself, sets the priority to LOW and waits for the temperature or available values to change before making any decision.
@property
def min_run_time()
Minimal run time for the water heater.
It is to prevent damage of the water heater by turning it on and off too frequently.
@property
def desired_temperature()
The desired water temperature.
@property
def temperature()
Current water temperature.
@property
def available()
Current water tank level expressed as percent.
def estimate_run_time()
Estimate the required time to reach the target temperature.
@property
def mode()
Return the Aquanta device active mode.
Usually one of 'away', 'boost' or 'timer'.
@Pyro5.api.expose
@Pyro5.api.oneway
def start()
Turn on the water heater.
@Pyro5.api.expose
@Pyro5.api.oneway
def stop()
Turn off the water heater.
If the water heater is running but has not been running for MIN_RUN_TIME, this function does not do anything.
@Pyro5.api.expose
def is_runnable()
True if the Task can be schedule.
def has_been_running_for()
Return the time the water heater has been running.
@Pyro5.api.expose
def is_stoppable()
Return True if it has been running for MIN_RUN_TIME.
@Pyro5.api.expose
def meet_running_criteria(ratio, power=0)
True if the water heater can be turned on or should keep running.
The water heater may not use any power while it is filling the tank and may stop using power or not starting using any power when the tank is full tank. This function attempt to detect the best it can when the water heater should be started or stopped.
-
If the water heater tank is full we expect that if started it would use power right away. If it does not we make the task not runnable for 'no_power_delay'.
-
If the water heater has been running for a little while and suddenly stop using power, we consider it the tank is full, the water fully heated and make the task not runnable for four times 'no_power_delay'.
@Pyro5.api.expose
@property
def desc()
String representation of the water heater task and status.
def adjust_priority()
Adjust the priority according to the status and target time.
If the temperature and the water availability has not changed since the last priority adjustment, the function aborts.
The priority is adjusted based on temperature and water availability thresholds.
If the priority is not the highest and we have less time than estimated to reach the target, the priority is artificially increased by one level.
def prevent_auto_start()
Prevent automatic turn on.
This function puts the Aquanta in away mode if the schedule is about to turn the water heater on. The away mode is set for the duration of the programmed ON schedule.
def today_schedule()
Return today's schedule as list of [start, stop] datetime.
def register(name, uri, raise_exception=True)
Register 'task' as sensor and task.
def device_exist_assert(device_id, aquanta)
Verify that 'device_id' exist for this aquanta account.
It exits with exit code data error if the device is not found or the device list could not be read.
def main()
Start and register a water heater Task and water heater Sensor.