chomupashchuk / ariston-aqua-remotethermo-home-assistant

Aqua Ariston NET Remotethermo for Home Assistant
MIT License
69 stars 26 forks source link

Request failing due to bad value #11

Closed BryceSoker closed 3 years ago

BryceSoker commented 3 years ago

I have a lydos_hybrid that basically from time to time fails to change the heater's state due to this error:

Error executing service: <ServiceCall aquaariston.aqua_set_data (c:1891b22d5dd77ec6bac764bd846b98f1): mode=i-memory, required_temperature=75, entity_id=['water_heater.aqua_ariston']>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 1461, in catch_exceptions
    await coro_or_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1484, in _execute_service
    await self._hass.async_add_executor_job(handler.job.target, service_call)
  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/aquaariston/__init__.py", line 257, in set_ariston_aqua_data
    api.ariston_api.set_http_data(**parameter_list)
  File "/config/custom_components/aquaariston/aristonaqua.py", line 1997, in set_http_data
    raise Exception("Following values could not be set: {}".format(bad_values))
Exception: Following values could not be set: {'required_temperature': 75.0}

My maximum temperature is 75, and I've also seen it happen when the temperature set is 70.

I am using a custom-scheduler (https://community.home-assistant.io/t/scheduler-card-custom-component/217458) with the yaml:

type: 'custom:scheduler-card'
include:
  - water_heater.aqua_ariston
time_step: 10
standard_configuration: false
customize:
  water_heater.aqua_ariston:
    name: Aqua Ariston
    icon: water-pump
    actions:
      - service: aquaariston.aqua_set_data
        service_data:
          entity_id: water_heater.aqua_ariston
          mode: green
          required_temperature: 40
        name: Set Green 40ºC
        icon: nature-people
      - service: aquaariston.aqua_set_data
        service_data:
          entity_id: water_heater.aqua_ariston
          mode: green
          required_temperature: 52
        name: Set Green 52ºC
        icon: nature-people
      - service: aquaariston.aqua_set_data
        service_data:
          entity_id: water_heater.aqua_ariston
          mode: i-memory
          required_temperature: 52
        name: Set I Memory 52ºC
        icon: memory
      - service: aquaariston.aqua_set_data
        service_data:
          entity_id: water_heater.aqua_ariston
          mode: i-memory
          required_temperature: 65
        name: Set I Memory 65ºC
        icon: memory
      - service: aquaariston.aqua_set_data
        service_data:
          entity_id: water_heater.aqua_ariston
          mode: i-memory
          required_temperature: 75
        name: Set I Memory 75ºC
        icon: memory
      - service: aquaariston.aqua_set_data
        service_data:
          entity_id: water_heater.aqua_ariston
          mode: boost
          required_temperature: 75
        name: Set Boost 75ºC
        icon: fast-forward

At first, I thought this might be sending strings or such but after giving the code a quick check I noticed that the data is always converted to string (? correct me if I'm wrong).

I'll try to keep looking for it and if I find the cause I'll add it here.

BryceSoker commented 3 years ago

**** me it needs to be a string. 75.0 should be '75'

Edit: Nope nevermind, same issue.

BryceSoker commented 3 years ago

Ok, I might've found the cause.

There is a check at line 1894 that verifies if the required_temperature is lower than the max temperature. However that max temperature is hardcoded to 70 even though that right now it can be changed on the Ariston App.

So instead of being a good developer I went the lazy, hammery path on those lines and simply allowed all temperatures to pass. If I ever decided to not be lazy and actually try to find the request that gets those max values from the server I will add a merge request to this. But for now this worked for me ( at least the service seems to be working fine):

 elif parameter in {
                  self._PARAM_REQUIRED_TEMPERATURE,
                  self._PARAM_CLEANSE_TEMPERATURE,
                  self._PARAM_REQUIRED_SHOWERS,
              }:
                  value = float(value)
                  if parameter == self._PARAM_REQUIRED_TEMPERATURE: <---------
                       good_values[parameter] = value <-----------------------
                       good_parameter = True <--------------------------------
                  if allowed_values[parameter] and allowed_values[parameter]["min"] - 0.01 <= value \
                          <= allowed_values[parameter]["max"] + 0.01 and parameter != self._PARAM_REQUIRED_TEMPERATURE: <--------------------------------
                      if parameter == self._PARAM_REQUIRED_SHOWERS:
                          good_values[parameter] = int(value)
                      else:
                          good_values[parameter] = value
                      good_parameter = True
              if not good_parameter:
                  bad_values[parameter] = value
          except KeyError:
              bad_values[parameter] = value
chomupashchuk commented 3 years ago

I do not have a boiler using Aqua Ariston, I have Clas Evo, which uses different integration. A guy who has lydos hybrid sent maximum values for different modes in the email. I had no direct access to the boiler and from provided requests data I did not see reported maximum values, so I hardcoded them based on current mode (70 for all except 53 for "green") from email. You may check line 657 in the code.

It is not a problem to replace values, but I need to know the ranges or specifics. You may also check the requests (I use fiddler on PC and enabled proxy to which I connected my android phone) if maximum is reported in some request to make it automated.

BryceSoker commented 3 years ago

Yeah, I assumed that was the case. I might get around to use fiddler and do just that.

For now, I will close this issue since this workaround worked for me but if I do get around to actually contribute and not just be a lazy bum I will add it to the repo.

BryceSoker commented 3 years ago

So I got around to use fiddler, the request is the following:

GET https://www.ariston-net.remotethermo.com/api/v2/velis/sePlantData/<ID>/plantSettings?appId=com.remotethermo.velis HTTP/1.1
ar.authToken: *************************************************************************************************************************************************************************************************************************************************************************************************
Accept: application/json, text/json, text/x-json, text/javascript, application/xml, text/xml
User-Agent: RestSharp/106.6.10.0
Host: www.ariston-net.remotethermo.com
Accept-Encoding: gzip, deflate

and the response body is the following:

{
  "SeAntilegionellaOnOff": 1,
  "SeAntiCoolingOnOff": 0,
  "SeNightModeOnOff": 0,
  "SePermanentBoostOnOff": 1,
  "SeMaxSetpointTemperature": 75,
  "SeMaxSetpointTemperatureMin": 65,
  "SeMaxSetpointTemperatureMax": 75,
  "SeAntiCoolingTemperature": 17,
  "SeAntiCoolingTemperatureMin": 10,
  "SeAntiCoolingTemperatureMax": 26,
  "SeMaxGreenSetpointTemperature": 53,
  "SeHeatingRate": 9,
  "SeNightBeginAsMinutes": 1380,
  "SeNightBeginMinAsMinutes": 1200,
  "SeNightBeginMaxAsMinutes": 120,
  "SeNightEndAsMinutes": 360,
  "SeNightEndMinAsMinutes": 240,
  "SeNightEndMaxAsMinutes": 600
}

where SeMaxSetpointTemperature is the new max temperature value (either way the max (of the max) seems to be 75). I will check if I can add it into the code, but it might take a bit so I will just leave it here.

chomupashchuk commented 3 years ago

It might be a bit tricky to include with other sensors, the request to fetch maximum should probably be sent only once (most likely after login) to have values during sensor setting. Since sensors have "actual" and "temporary" states during setting of data it is probably the easiest and safest way to go. I'm still a bit worried if this request is supported by all boilers or not (lydos hybrid had unique requests compared to lydos and velis), so for safety purposes setting maximum should be triggered only for this model.

Right now I'm including some updates in that file for logging purposes (if standalone API is used) and can try to include this as well.

chomupashchuk commented 3 years ago

aristonaqua.zip

Please try updated version. If there are issues, you may try to fix them and sent the updated version or let me know if something does not work. It would take too long for me to create unit test and mock everything for this to function properly.

chomupashchuk commented 3 years ago

I planned to publish updates today so if possible please let me know if it works soon.

BryceSoker commented 3 years ago

Alright, it seems to have worked.

So, thanks man!