Close
0%
0%

Calling for hot water, the recall

Updates and expands on my earlier project with new hardware at the water heater.

Similar projects worth following
In a previous project, Calling for hot water, https://hackaday.io/project/192719-calling-for-hot-water, I described a wireless IoT implementation for summoning hot water from my recirculation pump. This project describes re-implementing the part at the water heater end with some tidier off-the-shelf modules.

Since the project is a little bit iterative, details are provided in the project logs.

  • ESPHome implementation alternatives

    WJCarpenter20 hours ago 0 comments

    Besides the collaborative reverse-engineering effort documented in the forum thread, there are at least 2 concrete ESPHome interface configurations. They differ a bit in approach. The github repositories for both include documentation of the packet formats. They expect bytes to be read/written over the UART interface, implying a separate component that translates the microcontroller's logic levels to RS485 signals.

    The repository https://github.com/evanjarrett/ESPHome-Navien takes the approach of defining everything inside a YAML file. Debug logging within that configuration facilitates the iterative discovery process for reverse engineering. Most of the packet data bytes are made available as simple values, but some well-understood items are given semantically meaningful names. Some ideas for this repository seem to have been taken from or inspired by https://github.com/esphome-econet/esphome-econet.

    The repository https://github.com/htumanyan/navien takes the approach isolating the low-level manipulation into an ESPHome custom component. That simplifies the YAML configuration and, in the long term, is more consistent with how other components are usually referenced in ESPHome. However, it comes at the expense of being a bit more cumbersome for iterative discovery. Only a handful of data items are exposed as sensors and switches for use in YAML. Adding more requires manipulating the code for the custom component and making related changes to the YAML.

    There is also a non-ESPHome implementation in repository https://github.com/dacarson/NavienManager. It used Arduino environment but is still useful as an information source.

    My short-term aims are these:

    • Only read from the water heater; never write. That's just a safety measure. If something goes wrong, I can't be the case that I sent a command that gave the Navien brain damage. The only thing I'm really interested in commanding is the press of the Hot Button, which I am doing with the tried and true relay technique.
    • I want to be able to see when the recirculation pump turns off. That will let me give better user feedback for my remote button presses.

    Taking those into account and the current state of the two GitHub repositories, I plan to start with the pure YAML implementation. I'll observe for a while and then decide what to do.

  • Wires

    WJCarpenter21 hours ago 0 comments

    In the forum thread I mentioned, other people have already figured out the connectors and wiring arrangement for the Navien board's RS485 interface. For example, in this post, user aruffell provides this clear picture of a custom cable they created:

    The connector in the picture is a 5-pin JST-XH, though the slightly preferred connector is JST-XHB (the "B" is for "buckle", the integrated clip that keeps the connector from coming out). Both have been reported to work without issue.

    In this post, user tsquared shows the wiring with the connector inserted into the socket on the Navien board:

    RS485 uses differential signalling, and there is an A and a B signal line. Only 4 pins of the JST-XHB connector are used. Combining the info from the above pictures, the pin assignments are:

    1. 12vdc
    2. B
    3. A
    4. (not connected)
    5. Ground

    In addition to the RS485 wiring, there is also the relay wiring for the Hot Button feature. That's somewhat simpler since it's just 2 wires and orientation doesn't matter. They're connected to the relay pins Common and NO (normally open).

  • Software reconfiguration, part 1

    WJCarpenter2 days ago 0 comments

    As I mentioned, my first step is to ignore the RS485 stuff and get the hot button mechanism working with this new hardware setup. Because I used ESPHome, things are mostly abstracted. Here are the changes I made based on testing the new assembly:

    • Changed the node name to "hotbuttonrelay-al" ("al" for Atom Lite) to prevent a collision with the existing hardware.
    • Modify the board definition and the referenced GPIO pins for the button and the relay trigger.
    • I don't have an overly convenient way to wire in the BME280 climate sensor, so I just deleted that definition along with the I2C bus. (I have plenty of temperature sensors around the house, so no biggie).
    • The Atom Lite doesn't have the usual on-board LED of typical ESP8266 or ESP32 development boards. Instead, it has a more sophisticated RGB LED. I redefined that as an ESPHome RGB light object using the fastled platform. (The compilation of the fastled libraries always gives a pile of warnings, but they don't seem harmful so far.)
    • The mini relay board does not have an LED for visual feedback, so I configured the Atom Light LED to turn on and off colored green with the relay activation. Since the Atom Light is the same component used for the remote hot buttons, I cloned that bit of YAML to have it use the same hot and cold lighting effects. The relay activation uses 500ms. All the other handshaking and activity happens faster than that, so I put in a 600ms delay before the hot lighting effect starts. That lets me see the brief green signal for the relay activation.

    Here's the YAML so far:

    # https://hackaday.io/project/202744-calling-for-hot-water-the-recall
    
    substitutions:
      node_name: hotbuttonrelay-al
      RELAY:  'GPIO26'
      LED:    'GPIO27'
      BUTTON: 'GPIO39'
      log_level: 'DEBUG'
    
    esphome:
      name: ${node_name}
      on_boot:
        then:
          # delay to allow other boot time stuff to settle down
          - delay: 5s
          - script.execute: set_led_cold
    
    esp32:
      board: pico32
    
    wifi:
      ssid:      !secret wifi_ssid
      id:        !secret wifi_ssid
      password:  !secret wifi_password
      power_save_mode: high
      fast_connect: on
      manual_ip:
        static_ip: !secret hotbuttonrelay-al_ip
        gateway:   !secret wifi_gateway
        subnet:    !secret wifi_subnet
        dns1:      !secret wifi_dns1
        dns2:      !secret wifi_dns2
    
    logger:
       level: ${log_level}
    api:
      encryption:
        key: !secret hotbuttonrelay-al_apikey
      reboot_timeout: 60min
      services:
        - service: set_led_hot
          then:
            - logger.log:
                tag: 'hotbutton'
                level: INFO
                format: "service: set_led_hot"
            - script.execute: set_led_hot
        - service: set_led_cold
          then:
            - logger.log:
                tag: 'hotbutton'
                level: INFO
                format: "service: set_led_cold"
            - script.execute: set_led_cold
        - service: set_led_off
          then:
            - logger.log:
                tag: 'hotbutton'
                level: INFO
                format: "service: set_led_off"
            - script.execute: set_led_off
    
    ota:
      platform: esphome
      password: !secret ota_password
    
    switch:
      - platform: restart
        name: "${node_name} Reboot"
    
      - platform: gpio
        id: i_relay
        name: '${node_name} relay'
        pin: '${RELAY}'
        restore_mode: ALWAYS_OFF
        icon: mdi:hot-tub
        on_turn_on:
          - light.turn_on:
              id: bright_light
              red: 0%
              green: 100%
              blue: 0%
          - delay: 500ms
          - switch.turn_off: i_relay
          - light.turn_off:
              id: bright_light
    
    # Local test button. This goes through the relay logic, 
    # so it's not an analog press of the water heater button.
    binary_sensor:
      - platform: gpio
        name: "${node_name} Button"
        id: i_button
        pin:
          number: '${BUTTON}'
          inverted: true
          mode:
            input: true
        filters:
          - delayed_on: 10ms
          - delayed_off: 10ms
    
    light:
      - platform: fastled_clockless
        id: bright_light
        name: ${node_name} LED
        chipset: SK6812
        pin: '${LED}'
        num_leds: 1
        rgb_order: GRB # required
        default_transition_length: 0s
        icon: mdi:led-on
        effects:
          - pulse:
              name: fast_pulse
              transition_length: 0.25s
              update_interval: 0.25s
              min_brightness: 20%
              max_brightness: 99%
    
    script:
      - id: set_led_hot
        then:
          - delay: 600ms  # give the relay blink a chance to show
          - light.turn_on:
              id: bright_light
              red: 100%
              green: 60%
              blue: 0%
              effect: fast_pulse
    
      - id: set_led_cold
        then:
    ...
    Read more »

  • Physical assembly

    WJCarpenter3 days ago 0 comments

    The RS485 unit and the relay unit both have LEGO-compatible holes in their bodies. I decided to make a 3D-printed slab with a few LEGO studs in the right places to take advantage of that. I started with this nice custom LEGO component generating script: https://github.com/cfinke/LEGO.scad. My requirement was a little unusual, so I made a couple of local modifications to that OpenSCAD script.

    • The standard height for a LEGO stud in that script is 1.8mm. I wanted them taller to give a more snug fit, so I changed that to 8.0mm. That's no good for normal LEGO stacking, but it works great with the M5stack stuff.
    • I change the code a bit to suppress the generation of the studs except in the four locations where I wanted them. I spent a little time trying to see if I could parameterize that, but OpenSCAD makes that at best kind of klunky and hacky. If I later figure out a reasonably elegant way to do that, I'll send a PR to the author.

    The script does include a parametric scaling factor for the diameter size of the studs. Through trial and error, I settled on 1.01 (ie, 101%) to allow for filament shrinkage and still have a snug fit.

    Here are the bottom sides of the components along with the 6x6 base I created.

    And here is what it looks like when it's press-fit together:

    I think it makes a pretty tidy bundle. I haven't yet decided how I will mount this bundle to the water heater, but I'll probably use the refrigerator magnet technology I tried before. This bundle is a bit lighter than the bundle from the earlier project.

  • Hardware decisions

    WJCarpenter3 days ago 0 comments

    At the water heater end, requirements are minimal. Just about any ESP32 variant would fit the bill. I decided to use something from their Atom series since they are cheap and I already have some on hand. Specifically, I'll use an Atom Lite, which has two physical buttons and a single RGB LED. 

    They have a couple different RS485 interface components that will work with the Atom series. The cheapest option is their RS485 to TTL Converter Unit

    For a tiny amount more, their ATOM Tail485 - RS485 Converter for ATOM makes for a tidier package since it plugs directly into the Atom Lite.

    In the end, I didn't choose either of those. I spent a few bucks more and chose the ATOMIC RS485 Base.

    The reason for that choice is because it leaves the 4-pin port on the Atom Lite exposed. (It also leaves the USB-C port exposed for power, though once it's wired up to an RS485 circuit, that circuit can power everything.) I'm not sure if the reverse-engineered RS485 conversation will let me remotely "push the button" to call for hot water. For insurance, my first step will be to implement the hot button feature using a relay, as in the previous project. This Mini 3A Relay Unit interfaces to the Atom Lite via that 4-pin port.

    The total cost for these three components is under US$20, which is not too bad for a one-off project.

  • Project motivation

    WJCarpenter3 days ago 0 comments

    My original project has been operating for a while in a satisfactory way. I do still have one unsolved problem (knowing when the pump stops pumping), though for a while I've had some ideas about how to tackle that. In the meanwhile, some clever and industrious people over in the Home Assistant forums have been making progress on reverse engineering the wire protocol between Navien's NaviLink unit and the tankless water heater. I think that will give me the answer about the pump (not sure). To find out, I'll need an RS485 interface to the water heater control board.

    If you look around for an RS485 interface board (as some of the folks in that forum thread have done), you come across some components from M5stack. Their stuff is particularly appealing for one-off projects since it mostly comes in reasonably attractive packages. I already have a little box full of assorted M5stack stuff, so I decided to make use of that and a few things I had to order from them to re-implement the hardware.

View all 6 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates