Rheem Water Softener

Update code from git. In the morning I’ve changed interval to 5 minutes and for me from yesterday its working. Probably you must wait for throttling reset on API (time with less requests)

I kept it the way it 120 seconds and just added the integration again, and it worked. Shouldn’t we be ok with two minutes instead of five? Every two minutes is less than 1000 API calls a day.

Also, any chance you can add valve control? I think you mentioned you don’t have the valve, maybe some of us can chip in and buy you one. It can be added to any of these softeners pretty easily. You’d just need to pipe it in.

I never got an email from them (I did the HA integration maybe 2 weeks ago max), but my account is completely locked out. (bad user/pass). I have reset it, and I cannot login even from the app. I noticed that previously it was letting me login at 6:30am for a few minutes (guessing it was too many API calls in a few mins, so it locked me out.). I disabled the integration in HA days ago, and even the app doesn’t work at all. I am actually kinda pissed that they haven’t done anything to even try to turn me back on and allow at least the app to work!

Can you post photo what this valve looking and where is connected electrically? I’m afraid that my softener doesn’t have this option, I don’t have any settings and anything in app related to shut off valve.

Can you post photo what this valve looking and where is connected electrically? I’m afraid that my softener doesn’t have this option, I don’t have any settings and anything in app related to shut off valve.

Sure! This is the valve: https://www.homedepot.com/p/Rheem-Preferred-Series-Remote-Water-Shut-Off-Valve-7388598/316362390.

My unit didn’t come with it either, but there’s a place on the controller board to plug it in. Pictured below on the right, under the arrow. Sorry for the bad angle, it’s in a weird spot.

I figured out the value control thing. I missed it in my pcaps. It uses a HTTP PUT.

/v1/system/<serial>/properties

{"waterShutoffValve":1}

For turn on and

{"waterShutoffValve":0}

For turn off

Then when you have the valve integrated there is an addition property on the json return on the dashboard api call of:

"waterShutoffValveReq": {"value": 1 or 0}  1 for on and 0 for off

If I have time I can create a pull request later.

4 Likes

There’s no feedback if the valve actually closed after requesting?

Yeah there is a 200 OK response like the other api calls:

{
  "code": "OK",
  "message": "Operation is successfully executed",
  "data": [
    {
      "message": "Data Published Successfully.",
      "id": <id>
    }
  ]
}

K I got my patch done. Works great with my valve. If I have more time tonight, I’ll try to patch and create a switch for iqua-softener-homeassistant.

2 Likes

This happened to me too and I had to setup a new account with a new email address and then I had to re-pair the softener with the app.

someone said they are blacklisting the softners themselves now. I have a support ticket into them. Let’s see what the say. (I created it this morning, no response yet…)

Probably this operation publishes on AWS IoT service where device is connected. I’ve extracted certificates and identifier from flash and managed to connect this service by MQTT client and successfully receiving updates which device is publishing. This is better because don’t need polling but setup is more difficult - need connecting USB-serial adapter to PCB and download flash by esptool.

Thank for your pull request - I’ll try merge it today and write switch to HA integration.

This is sample of published data on AWS IoT broker:

{
    "previous": {
        "state": {
            "desired": {
                "Request": {
                    "regen_enable_enum": 1,
                    "user_lockout_enum": 0,
                    "time_format_enum": 1,
                    "volume_unit_enum": 1,
                    "hardness_unit_enum": 1,
                    "weight_unit_enum": 1,
                    "model_id": "108103",
                    "system_type": "demand softener",
                    "internet_connection_thr": 5,
                    "restore_connection_thr": 5,
                    "get_all_data": 1,
                    "flow_monitor_trip_sec": 1200,
                    "tz_id": "Europe/Warsaw",
                    "tz_dev": "CET-1CEST,M3.5.0,M10.5.0/3",
                    "regen_status_enum": 0,
                    "hardness_grains": 17,
                    "regen_time_secs": 7200,
                    "salt_type_enum": 0,
                    "feature_97pct_enum": 0,
                    "backwash_secs": 660,
                    "fast_rinse_secs": 300,
                    "second_backwash_secs": 660,
                    "max_days_between_regens": 0,
                    "rinse_type_enum": 1,
                    "aux_control_type_enum": 0,
                    "chem_feed_gals": 1,
                    "salt_level_tenths": 10,
                    "flow_monitor_min_rate_gpm": 4,
                    "chem_feed_tenths_secs": 1,
                    "iron_level_tenths_ppm": 0,
                    "efficiency_mode_enum": 1,
                    "date_format_enum": 1,
                    "salt_monitor_enum": 1,
                    "get_frequent_data": 267836777,
                    "language_enum": 0,
                    "app_active": 267605749
                }
            },
            "reported": {
                "UnitState": {
                    "gateway_connected": true,
                    "device_connected": true
                },
                "Request": {
                    "regen_enable_enum": 1,
                    "user_lockout_enum": 0,
                    "time_format_enum": 1,
                    "volume_unit_enum": 1,
                    "hardness_unit_enum": 1,
                    "weight_unit_enum": 1,
                    "model_id": "108103",
                    "system_type": "demand softener",
                    "internet_connection_thr": 5,
                    "restore_connection_thr": 5,
                    "get_all_data": 1,
                    "flow_monitor_trip_sec": 1200,
                    "regen_status_enum": 0,
                    "hardness_grains": 17,
                    "regen_time_secs": 7200,
                    "salt_type_enum": 0,
                    "feature_97pct_enum": 0,
                    "backwash_secs": 660,
                    "fast_rinse_secs": 300,
                    "second_backwash_secs": 660,
                    "max_days_between_regens": 0,
                    "rinse_type_enum": 1,
                    "aux_control_type_enum": 0,
                    "chem_feed_gals": 1,
                    "salt_level_tenths": 10,
                    "flow_monitor_min_rate_gpm": 4,
                    "chem_feed_tenths_secs": 1,
                    "iron_level_tenths_ppm": 0,
                    "efficiency_mode_enum": 1,
                    "date_format_enum": 1,
                    "salt_monitor_enum": 1,
                    "tz_id": "Europe/Warsaw",
                    "tz_dev": "CET-1CEST,M3.5.0,M10.5.0/3",
                    "get_frequent_data": 267836777,
                    "language_enum": 0,
                    "app_active": 267605749
                },
                "Status": {
                    "valve_motor_state_enum": 0,
                    "current_valve_position_enum": 2,
                    "wsov_installed": 0,
                    "water_shutoff_valve": 2,
                    "wsov_device_action": 0,
                    "model_id": 108103,
                    "model_description": "Aquahome Duo Smart",
                    "base_software_version": "r4.4 MPC01081",
                    "system_type": "demand softener",
                    "regen_status_enum": 0,
                    "avg_daily_use_gals": 65,
                    "gallons_used_today": 2,
                    "pwa_number": ...,
                    "build_date_code": 22151,
                    "valve_pos_switch_enum": 1,
                    "treated_water_avail_gals": 239,
                    "days_since_last_regen": 5,
                    "valve_pos_time_left_secs": 2276,
                    "regen_time_rem_secs": 0,
                    "current_time_secs": 63590,
                    "error_code": 0,
                    "rock_removed_since_rech_lbs": 240,
                    "current_water_flow_gpm": 0,
                    "out_of_salt_estimate_days": 57,
                    "water_counter_gals": 9,
                    "requested_valve_pos_enum": 2,
                    "aux_control_state_enum": 0,
                    "rf_signal_strength_dbm": -72,
                    "rf_signal_bars": 2,
                    "serial_number": "...",
                    "wsov_error_code": 0,
                    "esp_software_part_number": "...",
                    "product_serial_number": "...",
                    "ota_status_flag": 0,
                    "flow_monitor_alert": 0,
                    "excessive_water_use_alert": 0,
                    "wsov_manual_override": 0,
                    "error_code_alert": 0,
                    "low_salt_alert": 0,
                    "water_shutoff_valve_alert": 0,
                    "wsov_error_code_alert": 0,
                    "resin_alert": 0,
                    "total_outlet_water_gals": 11820,
                    "app_active": 0
                },
                "Errors": {
                    "10006": 0,
                    "10009": 0,
                    "10017": 0,
                    "10005": 0,
                    "10007": 0,
                    "10016": 0,
                    "11005": 0,
                    "11007": 0
                }
            }
        },
        "metadata": {
            "desired": {
                "Request": {
                    "regen_enable_enum": {
                        "timestamp": 1660224220
                    },
                    ... <removed timestamps for all fields> ...
                }
            }
        },
        "version": ...
    },
    "current": {
        "state": {
            "desired": {
                "Request": {
                    "regen_enable_enum": 1,
                    "user_lockout_enum": 0,
                    "time_format_enum": 1,
                    "volume_unit_enum": 1,
                    "hardness_unit_enum": 1,
                    "weight_unit_enum": 1,
                    "model_id": "108103",
                    "system_type": "demand softener",
                    "internet_connection_thr": 5,
                    "restore_connection_thr": 5,
                    "get_all_data": 1,
                    "flow_monitor_trip_sec": 1200,
                    "tz_id": "Europe/Warsaw",
                    "tz_dev": "CET-1CEST,M3.5.0,M10.5.0/3",
                    "regen_status_enum": 0,
                    "hardness_grains": 17,
                    "regen_time_secs": 7200,
                    "salt_type_enum": 0,
                    "feature_97pct_enum": 0,
                    "backwash_secs": 660,
                    "fast_rinse_secs": 300,
                    "second_backwash_secs": 660,
                    "max_days_between_regens": 0,
                    "rinse_type_enum": 1,
                    "aux_control_type_enum": 0,
                    "chem_feed_gals": 1,
                    "salt_level_tenths": 10,
                    "flow_monitor_min_rate_gpm": 4,
                    "chem_feed_tenths_secs": 1,
                    "iron_level_tenths_ppm": 0,
                    "efficiency_mode_enum": 1,
                    "date_format_enum": 1,
                    "salt_monitor_enum": 1,
                    "get_frequent_data": 267837977,
                    "language_enum": 0,
                    "app_active": 267605749
                }
            },
            "reported": {
                "UnitState": {
                    "gateway_connected": true,
                    "device_connected": true
                },
                "Request": {
                    "regen_enable_enum": 1,
                    "user_lockout_enum": 0,
                    "time_format_enum": 1,
                    "volume_unit_enum": 1,
                    "hardness_unit_enum": 1,
                    "weight_unit_enum": 1,
                    "model_id": "108103",
                    "system_type": "demand softener",
                    "internet_connection_thr": 5,
                    "restore_connection_thr": 5,
                    "get_all_data": 1,
                    "flow_monitor_trip_sec": 1200,
                    "regen_status_enum": 0,
                    "hardness_grains": 17,
                    "regen_time_secs": 7200,
                    "salt_type_enum": 0,
                    "feature_97pct_enum": 0,
                    "backwash_secs": 660,
                    "fast_rinse_secs": 300,
                    "second_backwash_secs": 660,
                    "max_days_between_regens": 0,
                    "rinse_type_enum": 1,
                    "aux_control_type_enum": 0,
                    "chem_feed_gals": 1,
                    "salt_level_tenths": 10,
                    "flow_monitor_min_rate_gpm": 4,
                    "chem_feed_tenths_secs": 1,
                    "iron_level_tenths_ppm": 0,
                    "efficiency_mode_enum": 1,
                    "date_format_enum": 1,
                    "salt_monitor_enum": 1,
                    "tz_id": "Europe/Warsaw",
                    "tz_dev": "CET-1CEST,M3.5.0,M10.5.0/3",
                    "get_frequent_data": 267836777,
                    "language_enum": 0,
                    "app_active": 267605749
                },
                "Status": {
                    "valve_motor_state_enum": 0,
                    "current_valve_position_enum": 2,
                    "wsov_installed": 0,
                    "water_shutoff_valve": 2,
                    "wsov_device_action": 0,
                    "model_id": 108103,
                    "model_description": "Aquahome Duo Smart",
                    "base_software_version": "r4.4 MPC01081",
                    "system_type": "demand softener",
                    "regen_status_enum": 0,
                    "avg_daily_use_gals": 65,
                    "gallons_used_today": 2,
                    "pwa_number": ...,
                    "build_date_code": 22151,
                    "valve_pos_switch_enum": 1,
                    "treated_water_avail_gals": 239,
                    "days_since_last_regen": 5,
                    "valve_pos_time_left_secs": 2276,
                    "regen_time_rem_secs": 0,
                    "current_time_secs": 63590,
                    "error_code": 0,
                    "rock_removed_since_rech_lbs": 240,
                    "current_water_flow_gpm": 0,
                    "out_of_salt_estimate_days": 57,
                    "water_counter_gals": 9,
                    "requested_valve_pos_enum": 2,
                    "aux_control_state_enum": 0,
                    "rf_signal_strength_dbm": -72,
                    "rf_signal_bars": 2,
                    "serial_number": "...",
                    "wsov_error_code": 0,
                    "esp_software_part_number": "...",
                    "product_serial_number": "...",
                    "ota_status_flag": 0,
                    "flow_monitor_alert": 0,
                    "excessive_water_use_alert": 0,
                    "wsov_manual_override": 0,
                    "error_code_alert": 0,
                    "low_salt_alert": 0,
                    "water_shutoff_valve_alert": 0,
                    "wsov_error_code_alert": 0,
                    "resin_alert": 0,
                    "total_outlet_water_gals": 11820,
                    "app_active": 0
                },
                "Errors": {
                    "10006": 0,
                    "10009": 0,
                    "10017": 0,
                    "10005": 0,
                    "10007": 0,
                    "10016": 0,
                    "11005": 0,
                    "11007": 0
                }
            }
        },
        .... <removed metadata section like this above> ...
}

When you look at status there are few entries related to valve, eg.:

                    "valve_motor_state_enum": 0,
                    "current_valve_position_enum": 2,
                    "wsov_installed": 0,
                    "water_shutoff_valve": 2,
                    "wsov_device_action": 0,
                    "valve_pos_switch_enum": 1,
                    "requested_valve_pos_enum": 2,

Your changes are merged and I did some cosmetical changes and renamed your method to set_water_shutoff_valve. For me (softener without valve) API still reporting waterShutoffValveReq field but with value of 2 - I suppose this enum is for softener without valve.

1 Like

Which version of Viessmann softener do you have?

Aquahome Duo SMART

What USB-serial adapter to PCB adapter did you use? I would totally like to give this a try…

I eventually got back in after I could login but couldn’t add my unit so they may have cleared it. I have been at 5 minutes for a couple of days and seems to be fine for now. Looking forward to using the MQTT to AWS method. My main desire for faster polling is water flow rate updates.

my account was also locked, but created a new one and managed to add softener on new account. I received two e-mails, one about removing device from old account and second about adding/registering device on second one. Looks like this is the way.
Anyone got account unlocked via support? for me polish support e-mail just returned “recipient address rejected”.

@arturzx this is using some REST API or directly MQTT? maybe we can point it to our local service by changing IP returned from DNS?

well, I have been working with support for a week, and they will not turn my account back on even though I have disabled the HA integration. I need to at least have the app work. I never got an email or any notification from them about anything. It just quit working. I told them the code has been fixed, but they keep saying “we are working with development”. I am like come on, just turn my account back on. They seem to not be doing that. I have not tried to create a new account, but I guess I could try that next.

Has anybody done any work/research on switching the mqtt to something local-ish?
What I did so far:

  1. redirect on the firewall directly to my mqtt server - no go, ssl handshake terminated by the client with “bad cert”
  2. created an NLB on AWS with mosquitto behind it. Planted an aws-signed cert on the NLB - still “bad cert”

looks like besides verifying the CA signature it also checks for the cert to match the hostname.
I haven’t tried setting up an AWS IoT server though.

Any luck with the firmware itself? Maybe they thought out of a possibilty to switch providers and something in the code allows it? Or certs can be swapped on the device to allow a local cert?
Happy to join the fight to make this device usable without the need of the EcoWater cloud.

p.s. When I asked the Polish branch of Ecowater for any instructions how to connect it to my local mqtt they said that this is hacking and is forbidden to use the softener with anything other then the iQua app :smiley:

I’ve use adapter bought 15 years ago, it is Polish production, probably not produced anymore. But this doesn’t matter. Any adapter should work but should have DTR and RTS pins, majority of adapters are simplified to VCC+GND+TX+RX pins, esptool use this two pins for reset microcontroller and boot serial bootloader. Boot Mode Selection - ESP32 - — esptool.py latest documentation

@JakubJ yes, I’ve done some work. Your problems coming from SSL client authentication, not server. AWS IoT using SSL client certificates and server authenticates client by this. Flashing own certificates it is not a problem, ESP32 in softener have partition named aws_certs with this content:

xxx.iot.yyy.amazonaws.com <- broker host
8883 <- port (used by Amazon AWS IoT MQTT service, 8883 is typical MQTT with SSL port)
20_88_1234567-Thing <- probably AWS IoT thing name, part of topics
<... 8 chars looks like random string ...>
88 <- number from client identifier?
20 <- second number from client identifier? This can be confirmed when someone other read flash and confirm this
<... 25 digit number - I don't know what is it ...>-----BEGIN CERTIFICATE-----
<... Amazon root CA to verify server...>
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
<... client key ...>
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
<... client certificate ...>
-----END CERTIFICATE-----<... zeros ...>

Months ago I’ve tried setup my AWS IoT server with no luck, but I spent little time with this and maybe do something wrong. I’ve tried to setup my local Mosquitto with SSL and flashing to softener own certs generated by me but softener had problems with connect to it. In Amazon documentation is mentioned that they modified MQTT and maybe this changes are not compatible with vanilla MQTT protocol. Last week I’ve setup AWS IoT SDK and successfully connected to AWS broker with certs read from softener, later I’ve managed to connect to it with normal MQTT client and receive updates which softener pushing. But when using AWS IoT SDK to connect my local SSL enabled Mosquitto connection can’t even get through handshake. Other thing - this using “device shadow” which is Amazon contract based on publishing/subscribing specific topics. AWS IoT Device Shadow service - AWS IoT Core
BTW. I sent PM to you.

@n3o REST API is used only by app, softener uses AWS IoT which is modified MQTT and for the reasons described above, it cannot be changed so easily.