Open hokiebrian opened 1 year ago
Amazing find. I will work on investigating on my end to see what all can be done.
I did some digging and there is just a few things missing from the local port as far as water heater information.
I currently have what I would call a hybrid solution up and running. I use the cloud to setup the integration and pull the water heater name, serial number, model, and the local IP address. I then set it up to use the local IP and port to make all the calls locally so no cloud calls are involved to change any values.
I thought about going full local and asking just the for host name, but currently that would require the integration to be removed and added back. I was thinking maybe we hold off on that unless we have enough people that want complete local. We only call the cloud on initial setup to get the missing information and only once on initial startup when your HA instance is restarted to maintain that information.
If you would like to try out an alpha version, I have created a branch dev-local
with all these new features that you could download and install on your HA instance to try out. I have been getting a couple errors, but I think I know what that is related to I just need to implement those fixes now.
I've tried to install from the dev-local branch, but HA does not populate with any devices or entities. HACS does not give me the option to install from dev-local branch even with allowing betas. If I try adding through custom repository menu HA states that it is available in the store. I installed 1.3.8, overwrote files in custom_components\rinnai with dev-local files, reboot, add integration, config flow succeeds, but only the integration update sensor is created. I am able to ncat to the host on 9798. Apologies as I'm not an HA expert
I have actually got an issue in this branch right now that I am working through. The local information does not come in clean at all, so I am sorting through all that.
I appreciate your time and efforts! Is the install process as I described correct?
Started playing with this myself.
The values from list
are live except for the ones prefixed with m. Pasting the output of list
below for any onlookers.
list
m01_water_flow_rate_raw: 9 (0x9) {116s}
m02_outlet_temperature: 133 (0x85) {115s}
m03_combustion_hours_raw: 0 (0x0) {2h}
m04_combustion_cycles: 0 (0x0) {2h}
m05_fan_frequency: 175 (0xaf) {110s}
m06_other_system_controllers: 101 (0x65) {2h}
m07_water_flow_control_position: 1 (0x1) {2h}
m08_inlet_temperature: 42 (0x2a) {106s}
m09_fan_current: 38 (0x26) {104s}
m10_total_bath_fill_volume: 0 (0x0) {2h}
m11_heat_exchanger_outlet_temperature: 136 (0x88) {101s}
m12_bypass_servo_position: 11 (0xb) {100s}
m13: null {-}
m14_internal_temperature: null {-}
m15_indoor_antifreeze_temperature: 61 (0x3d) {98s}
m16: null {-}
m17_outdoor_antifreeze_temperature: null {-}
m18: null {-}
m19_pump_hours: 0 (0x0) {2h}
m20_pump_cycles: 0 (0x0) {2h}
m21_exhaust_temperature: 66 (0x42) {94s}
ma__total_water_volume: null {-}
maintenance_list: '1,2,3,4,5,6,7,8,9,10,11,12,15,19,20,21,100,101,102,120,121,122' {2h}
mc__total_calories: null {-}
error_code: ' ' {2h}
lime_scale_error: null {-}
domestic_combustion: false {41s}
domestic_temperature: 135 (0x87) {93m}
recirculation_capable: true {2h}
recirculation_duration: null {-}
temperature_table: 2 (0x2) {2h}
module_start: null {-}
device_boot: null {-}
ap_mac_addr: '-----------' {2h}
public_ip: null {-}
local_ip: 'x.x.x.x' {2h}
wifi_channel_frequency: '2462' {2h}
wifi_signal_strength: '-80' {215s}
wifi_ssid: '---------' {2h}
recirculation_temperature: null {-}
zigbee_inventory: '[]' {2h}
zigbee_status: null {-}
warning_code: ' ' {2h}
do_maintenance_retrieval: null {85s}
lock_enabled: false {2h}
maximum_domestic_temperature: null {-}
minimum_domestic_temperature: null {-}
operation_enabled: true {2h}
priority_status: false {2h}
recirculation_enabled: false {244s}
recirculation_not_configured: null {-}
set_domestic_temperature:+ null {-}
set_operation_enabled: null {-}
set_priority_status: null {-}
set_recirculation_enabled: null {9m}
schedule:+ null {-}
schedule_enabled:+ null {-}
schedule_holiday:+ null {-}
timezone:+ 'PST8PDT,M3.2.0,M11.1.0' {2h}
heater_serial_number: null {-}
model: null {-}
module_firmware_version: '238' {2h}
module_log_level:+ null {-}
rinnai_registered: null {-}
do_zigbee: null {-}
baton_shadow: null {-}
baton_info: null {-}
exception: null {-}
ca_info: null {-}
Turning on trace mode makes the system output when a property changes it seems.
This looks interesting. Has the local stuff made it into the main release yet?
This has not yet. I have worked on it, but keep running into errors parsing all the data over time which seems to cause the local side to stop responding or locking up one of the two. I am still working on it though locally.
Hi @explosivo22 , Any details you can share about the parsing errors you're seeing or repro steps? I'd be happy to contribute some time and help out where possible.
This Rinnai integration enables our home’s most used and most loved automations. We would love to be able to run with local communcation. Thanks for all the work that has gone into the cloud version, and now the local version!
Hi @explosivo22 , Any details you can share about the parsing errors you're seeing or repro steps? I'd be happy to contribute some time and help out where possible.
@sazwerner I have managed to get this branch at least what I would consider stable. I have been running it for a couple months and have only saw a couple errors in the log related to connection issues which I attribute to network or just HA issues. The hardest part is everything from this connection comes back as byte data and parsing the correct location is the hardest part.
This Rinnai integration enables our home’s most used and most loved automations. We would love to be able to run with local communcation. Thanks for all the work that has gone into the cloud version, and now the local version!
@TesLocker Currently I have this as what I would consider hybrid. I use the cloud initially to grab the name and device IP reported. I then make the connection locally and continue doing only local calls after setup. I am still working on the full local solution, but anyone could test this out now if you manually install the dev-local branch files. You will need to remove the integration first due to the differences in the setup process currently. I plan to continue working on this though.
Well had a good day. Set up a powershell script to increase polling to every 15 seconds for starters to get an idea on how often the Rinnai would update. As it turns out, it updates fairly reasonably and depends on if it is actually heating or not. While it is heating, updates are as frequent as every 10-60 seconds. I finally got a graph and useful numbers for flow rate! Getting actual flow data is harder because water actually has to be moving during a polling session. So if you want more action on your flow graph, try to change the flow rate every 30 seconds or so :)...... So it looks like running this local is doable. Having a dial that you could set so that you could adjust the poll rate to suit your style, on the fly via node-red etc.. would be good.
I'm looking into installing a Rinnai tankless heater in my house (it would have the new RWM200 module, though I imagine the protocol must be largely identical to the older ones) and came across this, and I'm wondering what the current status is. Also, is the recirculation pump controllable locally with the alpha branch, or does that control still go through the cloud?
I got the new RWM200 hoping it would work for this too, but not seeing any TCP ports open on the newer module...
~# nmap -A -v -p1-65535 192.168.3.249
Starting Nmap 7.93 ( https://nmap.org ) at 2024-06-23 00:06 UTC
Initiating ARP Ping Scan at 00:06
Scanning 192.168.3.249 [1 port]
Completed ARP Ping Scan at 00:06, 0.38s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 00:06
Completed Parallel DNS resolution of 1 host. at 00:06, 0.00s elapsed
Initiating SYN Stealth Scan at 00:06
Scanning espressif.lan (192.168.3.249) [65535 ports]
Completed SYN Stealth Scan at 00:06, 36.53s elapsed (65535 total ports)
Initiating Service scan at 00:06
Initiating OS detection (try #1) against espressif.lan (192.168.3.249)
Retrying OS detection (try #2) against espressif.lan (192.168.3.249)
Nmap scan report for espressif.lan (192.168.3.249)
Host is up (0.013s latency).
All 65535 scanned ports on espressif.lan (192.168.3.249) are in ignored states.
Not shown: 65535 closed tcp ports (reset)
MAC Address: xx:xx:xx:xx:xx:xx (Espressif)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: 2N Helios IP VoIP doorbell (95%), Advanced Illumination DCS-100E lighting controller (95%), AudioControl D3400 network amplifier (95%), British Gas GS-Z3 data logger (95%), Daysequerra M4.2SI radio (95%), Denver Electronics AC-5000W MK2 camera (95%), DTE Energy Bridge (lwIP stack) (95%), Enlogic PDU (FreeRTOS/lwIP) (95%), Espressif esp8266 firmware (lwIP stack) (95%), Espressif ESP8266 WiFi system-on-a-chip (95%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 1 hop
TRACEROUTE
HOP RTT ADDRESS
1 13.14 ms espressif.lan (192.168.3.249)
Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 49.74 seconds
Raw packets sent: 65998 (2.905MB) | Rcvd: 65555 (2.623MB)
I see 49778 open for UDP, and can send packets there, but not seeing any way to get a response. tcpdump -i any udp and host <device>
only gets me my outgoing packets when I try the commands above. I haven't played with this kind of UDP discovery in the past, so would be interested if anyone has any other ideas to test.
PORT STATE SERVICE VERSION
49778/udp open|filtered unknown
@dmzimmerman I'm looking into installing a Rinnai tankless heater in my house (it would have the new RWM200 module, though I imagine the protocol must be largely identical to the older ones) and came across this, and I'm wondering what the current status is. Also, is the recirculation pump controllable locally with the alpha branch, or does that control still go through the cloud?
I missed this, but currently everything is ran through the cloud so I would assume if the app works then this would work. I missed the announcement about the RWM200 module, but looks like I will need to be getting on to test.
Seeing that the RWM200 doesn't have the open port, maybe I'll actually pick up an RWM103 instead and try that first. Unless they broke somethign on the current year's models, it should still work (and if it doesn't, I can always return it and get the 200).
Seeing that the RWM200 doesn't have the open port, maybe I'll actually pick up an RWM103 instead and try that first. Unless they broke somethign on the current year's models, it should still work (and if it doesn't, I can always return it and get the 200).
I would recommend this based on what I'm seeing. Clearly the module is still getting commands from the cloud provider, but ~may~ would be poll, and not sure if there's a simple way to interact directly (but happy to pursue if anyone has better ideas to try). I'm not sure the selling point of the RWM200 at this point.
I've ordered the RWM103. When my RXP199iN is installed in a couple of weeks, I'll try to set the module up, see how it goes, and report back (because if it doesn't work with the current models, that's potentially useful info for anyone following this issue).
To follow up, my RXP199iN was installed this week and the RWM103 works fine with it. I'm not quite sure about how the triggering of the recirculating pump works, or is supposed to work. I can tell it to turn on for 5 minutes in HA, but sometimes it seems like it stays on for 9 or 10; is that likely a result of the frequency of polling?
How, if I wanted to, would I go about installing the version that takes advantage of the local access to the RWM103? So far I've just installed the release version from HACS.
I’m also interested in installing the dev-local version. Any chance someone can post the instructions on how to properly set up the alternate branch?
I’m also interested in installing the dev-local version. Any chance someone can post the instructions on how to properly set up the alternate branch?
I am currently working on finishing this up to be fully local. I have a couple things around the host IP during the config flow to finish and I can get a dev release out.
If you would like to test out the all local version, I believe I have a stable version. This will require you to setup your integration again since the backend setup and naming scheme has changed due to some attributes missing so you may need to fix some automations. You can copy everything inside the custom_components/rinnaicontrolr-ha folder into the config/custom_components/rinnai folder if you would like to do this manually and start testing now.
I can make a release if that would make it easier to install from HACS, but I will have to be sure to put some notes since this will require setting up again and that the RWM200 doesn't work as of now.
Has anyone been able to test this? I’m hesitant to move off of the existing (very stable) implementation to a beta version when our family has gotten used to relying so heavily on hot water being automatically circulated and available.
At the same time, I appreciate all the hard work the explosivo22 has put into this local version.
I haven't done any troubleshooting, but when initially installing on a clean HA instance, I get: Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/config_entries.py", line 635, in async_setup_with_context result = await component.async_setup_entry(hass, self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/rinnai/init__.py", line 43, in async_setup_entry coordinator = RinnaiDeviceDataUpdateCoordinator(hass, sysinfo["sysinfo"]["local-ip"],sysinfo["sysinfo"]["serial-number"],sysinfo["sysinfo"]["serial-number"],sysinfo["sysinfo"]["ayla-dsn"], update_interval, entry.options)
KeyError: 'ayla-dsn'
I don't currently have an automations for my water heater in HA so in the next couple of days I will add it as an update and see how it goes then wipe and try again perhaps as new.
Just got a lot going on at work, so it may not be before the weekend, but would love this to be fully local so I'll give it a test for you.
I’m up for testing local.
I’ve heard (don’t remember where—it may have even been here someplace) that the water heater needs to circulate regularly. Are there any built-in behaviors that will stop working by going local? Are there actions we will need to emulate ourselves?
Has anyone been able to test this? I’m hesitant to move off of the existing (very stable) implementation to a beta version when our family has gotten used to relying so heavily on hot water being automatically circulated and available.
At the same time, I appreciate all the hard work the explosivo22 has put into this local version.
I have been running it and has been pretty solid for me, but I'm a single use case.
I haven't done any troubleshooting, but when initially installing on a clean HA instance, I get: Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/config_entries.py", line 635, in async_setup_with_context result = await component.async_setup_entry(hass, self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/rinnai/init__.py", line 43, in async_setup_entry coordinator = RinnaiDeviceDataUpdateCoordinator(hass, sysinfo["sysinfo"]["local-ip"],sysinfo["sysinfo"]["serial-number"],sysinfo["sysinfo"]["serial-number"],sysinfo["sysinfo"]["ayla-dsn"], update_interval, entry.options)
KeyError: 'ayla-dsn'
This is interesting. I would think they all have this value, but would need to do more digging or just change this.
I don't currently have an automations for my water heater in HA so in the next couple of days I will add it as an update and see how it goes then wipe and try again perhaps as new.
Just got a lot going on at work, so it may not be before the weekend, but would love this to be fully local so I'll give it a test for you.
Awesome. Looking forward to how it goes for you.
I’m up for testing local.
I’ve heard (don’t remember where—it may have even been here someplace) that the water heater needs to circulate regularly. Are there any built-in behaviors that will stop working by going local? Are there actions we will need to emulate ourselves?
If you have any automations now, you would need to set them back up with the new entity due to the renaming scheme and new setup with IP. The only thing we lost from the cloud was a model. All the same functions should still be there: on, off, set temp, start and stop recirculation.
@explosivo22 which branch should I pull from to install the local only version?
OK. I initially had a similar "key error" as above, but reloading the integration fixed it. Things seemed to be working as normal. However, looking today at my logs, I found this error:
This error originated from a custom integration.
Logger: homeassistant
Source: custom_components/rinnai/device.py:168
integration: Rinnai Control-R Water Heater (documentation)
First occurred: November 21, 2024 at 11:33:54 PM (2717 occurrences)
Last logged: 7:10:10 PM
Error doing job: Task exception was never retrieved (None)
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 1056, in _async_update_entity_states
await asyncio.gather(*tasks)
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 962, in async_update_ha_state
self._async_write_ha_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1132, in _async_write_ha_state
self.__async_calculate_state()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1069, in __async_calculate_state
state = self._stringify_state(available)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1013, in _stringify_state
if (state := self.state) is None:
^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 544, in state
value = self.native_value
^^^^^^^^^^^^^^^^^
File "/config/custom_components/rinnai/sensor.py", line 203, in native_value
if self._device.pump_cycles is None:
^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/rinnai/device.py", line 168, in pump_cycles
return float(self._device_info['m20_pump_cycles'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: could not convert string to float: 'null'
Note the "2717 occurrences" -- any idea what this is from? Did I misconfigure it?
@explosivo22 which branch should I pull from to install the local only version?
@sirmeili the dev-local branch will be fully local. I don't have a release created so you will have to manually do it
OK. I initially had a similar "key error" as above, but reloading the integration fixed it. Things seemed to be working as normal. However, looking today at my logs, I found this error:
This error originated from a custom integration. Logger: homeassistant Source: custom_components/rinnai/device.py:168 integration: Rinnai Control-R Water Heater (documentation) First occurred: November 21, 2024 at 11:33:54 PM (2717 occurrences) Last logged: 7:10:10 PM Error doing job: Task exception was never retrieved (None) Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 1056, in _async_update_entity_states await asyncio.gather(*tasks) File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 962, in async_update_ha_state self._async_write_ha_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1132, in _async_write_ha_state self.__async_calculate_state() File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1069, in __async_calculate_state state = self._stringify_state(available) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1013, in _stringify_state if (state := self.state) is None: ^^^^^^^^^^ File "/usr/src/homeassistant/homeassistant/components/sensor/__init__.py", line 544, in state value = self.native_value ^^^^^^^^^^^^^^^^^ File "/config/custom_components/rinnai/sensor.py", line 203, in native_value if self._device.pump_cycles is None: ^^^^^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/rinnai/device.py", line 168, in pump_cycles return float(self._device_info['m20_pump_cycles']) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ValueError: could not convert string to float: 'null'
Note the "2717 occurrences" -- any idea what this is from? Did I misconfigure it?
@bobwithanx I'm glad you got it working. I have seen this when it doesn't read everything fully from the socket. I haven't been able to fully narrow it down to if it is signal strength or if it is related to something else yet. I continue to investigate, but sockets make it a little harder since I don't actually get any errors just incomplete results back from the heater.
I got it added but get the following:
2024-11-22 21:51:22.422 ERROR (MainThread) [homeassistant.config_entries] Error setting up entry [redacted]for rinnai Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/config_entries.py", line 635, in async_setup_with_context result = await component.async_setup_entry(hass, self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/rinnai/init.py", line 43, in async_setup_entry coordinator = RinnaiDeviceDataUpdateCoordinator(hass, sysinfo["sysinfo"]["local-ip"],sysinfo["sysinfo"]["serial-number"],sysinfo["sysinfo"]["serial-number"],sysinfo["sysinfo"]["ayla-dsn"], update_interval, entry.options) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/rinnai/device.py", line 36, in init__ self.maint_refresh_interval = timedelta(seconds=self.options[CONF_MAINT_REFRESH_INTERVAL])
KeyError: 'maint_refresh_interval'
Just a note that I clicked "configure" and changed the maintenance refresh level to something other than 300 and saved. Then it worked. I then could set it back to 300 and it still is working.
Edit: I also noticed it is showing as 13 entities instead of 1 device. Is that expected for now? The old one showed it as a single device.
edit2: I'm impatient. it now shows as a device.
@bobwithanx I'm glad you got it working. I have seen this when it doesn't read everything fully from the socket. I haven't been able to fully narrow it down to if it is signal strength or if it is related to something else yet. I continue to investigate, but sockets make it a little harder since I don't actually get any errors just incomplete results back from the heater.
How can I help to diagnose / test this?
I’m curious — what clues have indicated it could be a signal strength issue? I haven’t noticed any signal issues prior to the local code. Wouldn’t the connection between the network and the heater be the same? Or am I misunderstanding your comment?
And serious props to you, @explosivo22, for your persistence and ingenuity getting it this far!
I am able to connect locally to my Control R Module.
ncat 192.168.x.x 9798
monitor help for help
Typing "list" gives all the properties that are seen in the cloud. This does not require any auth to access. From what I can gather, it is the same data that is current in the cloud - it isn't actually "real time". Anyone know anything more about this console?
"help" shows all commands, many available.
Also, port 9799 is open. When connecting, get "{"protocol":[1]}" - I have no idea what that might be for.
Anyways - it's local and requires no auth. That was attractive. I can do a custom sensor to pull the data, it's just updated at the maintenance interval though and I'm not sure how to trigger that using the port 9798 console.